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, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "config.h"
21 
22 #include "gck/gck.h"
23 
24 #include "gcr-internal.h"
25 #include "gcr-openpgp.h"
26 #include "gcr-openssh.h"
27 #include "gcr-parser.h"
28 #include "gcr-record.h"
29 #include "gcr-types.h"
30 
31 #include "gcr/gcr-marshal.h"
32 #include "gcr/gcr-oids.h"
33 
34 #include "egg/egg-armor.h"
35 #include "egg/egg-asn1x.h"
36 #include "egg/egg-asn1-defs.h"
37 #include "egg/egg-dn.h"
38 #include "egg/egg-openssl.h"
39 #include "egg/egg-secure-memory.h"
40 #include "egg/egg-symkey.h"
41 
42 #include <glib/gi18n-lib.h>
43 
44 #include <stdlib.h>
45 #include <gcrypt.h>
46 
47 /**
48  * SECTION:gcr-parser
49  * @title: GcrParser
50  * @short_description: Parser for certificate and key files
51  *
52  * A #GcrParser can parse various certificate and key files such as OpenSSL
53  * PEM files, DER encoded certifictes, PKCS\#8 keys and so on. Each various
54  * format is identified by a value in the #GcrDataFormat enumeration.
55  *
56  * In order to parse data, a new parser is created with gcr_parser_new() and
57  * then the #GcrParser::authenticate and #GcrParser::parsed signals should be
58  * connected to. Data is then fed to the parser via gcr_parser_parse_data()
59  * or gcr_parser_parse_stream().
60  *
61  * During the #GcrParser::parsed signal the attributes that make up the currently
62  * parsed item can be retrieved using the gcr_parser_get_parsed_attributes()
63  * function.
64  */
65 
66 /**
67  * GcrParser:
68  *
69  * A parser for parsing various types of files or data.
70  */
71 
72 /**
73  * GcrParsed:
74  *
75  * A parsed item parsed by a #GcrParser.
76  */
77 
78 /**
79  * GcrParserClass:
80  * @parent_class: The parent class
81  * @authenticate: The default handler for the authenticate signal.
82  * @parsed: The default handler for the parsed signal.
83  *
84  * The class for #GcrParser
85  */
86 
87 /**
88  * GCR_DATA_ERROR:
89  *
90  * A domain for data errors with codes from #GcrDataError
91  */
92 
93 /**
94  * GcrDataError:
95  * @GCR_ERROR_FAILURE: Failed to parse or serialize the data
96  * @GCR_ERROR_UNRECOGNIZED: The data was unrecognized or unsupported
97  * @GCR_ERROR_CANCELLED: The operation was cancelled
98  * @GCR_ERROR_LOCKED: The data was encrypted or locked and could not be unlocked.
99  *
100  * Values responding to error codes for parsing and serializing data.
101  */
102 
103 enum {
104 	PROP_0,
105 	PROP_PARSED_LABEL,
106 	PROP_PARSED_ATTRIBUTES,
107 	PROP_PARSED_DESCRIPTION
108 };
109 
110 enum {
111 	AUTHENTICATE,
112 	PARSED,
113 	LAST_SIGNAL
114 };
115 
116 #define SUCCESS 0
117 
118 static guint signals[LAST_SIGNAL] = { 0 };
119 
120 struct _GcrParsed {
121 	gint refs;
122 	GckBuilder builder;
123 	GckAttributes *attrs;
124 	const gchar *description;
125 	gchar *label;
126 	GBytes *data;
127 	gboolean sensitive;
128 	GcrDataFormat format;
129 	gchar *filename;
130 	struct _GcrParsed *next;
131 };
132 
133 struct _GcrParserPrivate {
134 	GTree *specific_formats;
135 	gboolean normal_formats;
136 	GPtrArray *passwords;
137 	GcrParsed *parsed;
138 	gchar *filename;
139 };
140 
141 G_DEFINE_TYPE_WITH_PRIVATE (GcrParser, gcr_parser, G_TYPE_OBJECT);
142 
143 typedef struct {
144 	gint ask_state;
145 	gint seen;
146 } PasswordState;
147 
148 #define PASSWORD_STATE_INIT { 0, 0 }
149 
150 typedef struct _ParserFormat {
151 	gint format_id;
152 	gint (*function) (GcrParser *self, GBytes *data);
153 } ParserFormat;
154 
155 /* Forward declarations */
156 static const ParserFormat parser_normal[];
157 static const ParserFormat parser_formats[];
158 static ParserFormat* parser_format_lookup (gint format_id);
159 
160 EGG_SECURE_DECLARE (parser);
161 
162 /* -----------------------------------------------------------------------------
163  * QUARK DEFINITIONS
164  */
165 
166 /*
167  * PEM STRINGS
168  * The xxxxx in: ----- BEGIN xxxxx ------
169  */
170 
171 static GQuark PEM_CERTIFICATE;
172 static GQuark PEM_RSA_PRIVATE_KEY;
173 static GQuark PEM_DSA_PRIVATE_KEY;
174 static GQuark PEM_EC_PRIVATE_KEY;
175 static GQuark PEM_ANY_PRIVATE_KEY;
176 static GQuark PEM_ENCRYPTED_PRIVATE_KEY;
177 static GQuark PEM_PRIVATE_KEY;
178 static GQuark PEM_PKCS7;
179 static GQuark PEM_PKCS12;
180 static GQuark PEM_CERTIFICATE_REQUEST;
181 static GQuark PEM_NEW_CERTIFICATE_REQUEST;
182 static GQuark PEM_PUBLIC_KEY;
183 
184 static GQuark ARMOR_PGP_PUBLIC_KEY_BLOCK;
185 static GQuark ARMOR_PGP_PRIVATE_KEY_BLOCK;
186 
187 static void
init_quarks(void)188 init_quarks (void)
189 {
190 	static volatile gsize quarks_inited = 0;
191 
192 	if (g_once_init_enter (&quarks_inited)) {
193 
194 		#define QUARK(name, value) \
195 			name = g_quark_from_static_string(value)
196 
197 		QUARK (PEM_CERTIFICATE, "CERTIFICATE");
198 		QUARK (PEM_PRIVATE_KEY, "PRIVATE KEY");
199 		QUARK (PEM_RSA_PRIVATE_KEY, "RSA PRIVATE KEY");
200 		QUARK (PEM_DSA_PRIVATE_KEY, "DSA PRIVATE KEY");
201 		QUARK (PEM_EC_PRIVATE_KEY, "EC PRIVATE KEY");
202 		QUARK (PEM_ANY_PRIVATE_KEY, "ANY PRIVATE KEY");
203 		QUARK (PEM_ENCRYPTED_PRIVATE_KEY, "ENCRYPTED PRIVATE KEY");
204 		QUARK (PEM_PKCS7, "PKCS7");
205 		QUARK (PEM_PKCS12, "PKCS12");
206 		QUARK (PEM_CERTIFICATE_REQUEST, "CERTIFICATE REQUEST");
207 		QUARK (PEM_NEW_CERTIFICATE_REQUEST, "NEW CERTIFICATE REQUEST");
208 		QUARK (PEM_PUBLIC_KEY, "PUBLIC KEY");
209 
210 		QUARK (ARMOR_PGP_PRIVATE_KEY_BLOCK, "PGP PRIVATE KEY BLOCK");
211 		QUARK (ARMOR_PGP_PUBLIC_KEY_BLOCK, "PGP PUBLIC KEY BLOCK");
212 
213 		#undef QUARK
214 
215 		g_once_init_leave (&quarks_inited, 1);
216 	}
217 }
218 
219 /* -----------------------------------------------------------------------------
220  * INTERNAL
221  */
222 
223 static void
parsed_attribute(GcrParsed * parsed,CK_ATTRIBUTE_TYPE type,gconstpointer data,gsize n_data)224 parsed_attribute (GcrParsed *parsed,
225                   CK_ATTRIBUTE_TYPE type,
226                   gconstpointer data,
227                   gsize n_data)
228 {
229 	g_assert (parsed != NULL);
230 	gck_builder_add_data (&parsed->builder, type, data, n_data);
231 }
232 
233 static void
parsed_attribute_bytes(GcrParsed * parsed,CK_ATTRIBUTE_TYPE type,GBytes * data)234 parsed_attribute_bytes (GcrParsed *parsed,
235                         CK_ATTRIBUTE_TYPE type,
236                         GBytes *data)
237 {
238 	g_assert (parsed != NULL);
239 	gck_builder_add_data (&parsed->builder, type,
240 	                      g_bytes_get_data (data, NULL),
241 	                      g_bytes_get_size (data));
242 }
243 
244 static gboolean
parsed_asn1_number(GcrParsed * parsed,GNode * asn,const gchar * part,CK_ATTRIBUTE_TYPE type)245 parsed_asn1_number (GcrParsed *parsed,
246                     GNode *asn,
247                     const gchar *part,
248                     CK_ATTRIBUTE_TYPE type)
249 {
250 	GBytes *value;
251 
252 	g_assert (asn);
253 	g_assert (parsed);
254 
255 	value = egg_asn1x_get_integer_as_usg (egg_asn1x_node (asn, part, NULL));
256 	if (value == NULL)
257 		return FALSE;
258 
259 	parsed_attribute_bytes (parsed, type, value);
260 	g_bytes_unref (value);
261 	return TRUE;
262 }
263 
264 static gboolean
parsed_asn1_element(GcrParsed * parsed,GNode * asn,const gchar * part,CK_ATTRIBUTE_TYPE type)265 parsed_asn1_element (GcrParsed *parsed,
266                      GNode *asn,
267                      const gchar *part,
268                      CK_ATTRIBUTE_TYPE type)
269 {
270 	GBytes *value;
271 
272 	g_assert (asn);
273 	g_assert (parsed);
274 
275 	value = egg_asn1x_get_element_raw (egg_asn1x_node (asn, part, NULL));
276 	if (value == NULL)
277 		return FALSE;
278 
279 	parsed_attribute_bytes (parsed, type, value);
280 	g_bytes_unref (value);
281 	return TRUE;
282 }
283 
284 static gboolean
parsed_asn1_structure(GcrParsed * parsed,GNode * asn,CK_ATTRIBUTE_TYPE type)285 parsed_asn1_structure (GcrParsed *parsed,
286                       GNode *asn,
287                       CK_ATTRIBUTE_TYPE type)
288 {
289 	GBytes *value;
290 
291 	g_assert (asn);
292 	g_assert (parsed);
293 
294 	value = egg_asn1x_encode (asn, g_realloc);
295 	if (value == NULL)
296 		return FALSE;
297 
298 	parsed_attribute_bytes (parsed, type, value);
299 	g_bytes_unref (value);
300 	return TRUE;
301 }
302 
303 static void
parsed_ulong_attribute(GcrParsed * parsed,CK_ATTRIBUTE_TYPE type,gulong value)304 parsed_ulong_attribute (GcrParsed *parsed,
305                         CK_ATTRIBUTE_TYPE type,
306                         gulong value)
307 {
308 	g_assert (parsed != NULL);
309 	gck_builder_add_ulong (&parsed->builder, type, value);
310 }
311 
312 static void
parsed_boolean_attribute(GcrParsed * parsed,CK_ATTRIBUTE_TYPE type,gboolean value)313 parsed_boolean_attribute (GcrParsed *parsed,
314                           CK_ATTRIBUTE_TYPE type,
315                           gboolean value)
316 {
317 	g_assert (parsed != NULL);
318 	gck_builder_add_boolean (&parsed->builder, type, value);
319 }
320 
321 
322 static void
parsing_block(GcrParsed * parsed,gint format,GBytes * data)323 parsing_block (GcrParsed *parsed,
324                gint format,
325                GBytes *data)
326 {
327 	g_assert (parsed != NULL);
328 	g_assert (data != NULL);
329 	g_assert (format != 0);
330 	g_assert (parsed->data == NULL);
331 
332 	parsed->format = format;
333 	parsed->data = g_bytes_ref (data);
334 }
335 
336 static void
parsed_description(GcrParsed * parsed,CK_OBJECT_CLASS klass)337 parsed_description (GcrParsed *parsed,
338                     CK_OBJECT_CLASS klass)
339 {
340 	g_assert (parsed != NULL);
341 	switch (klass) {
342 	case CKO_PRIVATE_KEY:
343 		parsed->description = _("Private Key");
344 		break;
345 	case CKO_CERTIFICATE:
346 		parsed->description = _("Certificate");
347 		break;
348 	case CKO_PUBLIC_KEY:
349 		parsed->description = _("Public Key");
350 		break;
351 	case CKO_GCR_GNUPG_RECORDS:
352 		parsed->description = _("PGP Key");
353 		break;
354 	case CKO_GCR_CERTIFICATE_REQUEST:
355 		parsed->description = _("Certificate Request");
356 		break;
357 	default:
358 		parsed->description = NULL;
359 		break;
360 	}
361 }
362 
363 static void
parsing_object(GcrParsed * parsed,CK_OBJECT_CLASS klass)364 parsing_object (GcrParsed *parsed,
365                 CK_OBJECT_CLASS klass)
366 {
367 	g_assert (parsed != NULL);
368 
369 	gck_builder_clear (&parsed->builder);
370 	if (parsed->sensitive)
371 		gck_builder_init_full (&parsed->builder, GCK_BUILDER_SECURE_MEMORY);
372 	else
373 		gck_builder_init_full (&parsed->builder, GCK_BUILDER_NONE);
374 	gck_builder_add_ulong (&parsed->builder, CKA_CLASS, klass);
375 	parsed_description (parsed, klass);
376 }
377 
378 static void
parsed_attributes(GcrParsed * parsed,GckAttributes * attrs)379 parsed_attributes (GcrParsed *parsed,
380                    GckAttributes *attrs)
381 {
382 	gulong klass;
383 
384 	g_assert (parsed != NULL);
385 	g_assert (attrs != NULL);
386 
387 	if (gck_attributes_find_ulong (attrs, CKA_CLASS, &klass))
388 		parsed_description (parsed, klass);
389 	gck_builder_add_all (&parsed->builder, attrs);
390 }
391 
392 static void
parsed_label(GcrParsed * parsed,const gchar * label)393 parsed_label (GcrParsed *parsed,
394               const gchar *label)
395 {
396 	g_assert (parsed != NULL);
397 	g_assert (parsed->label == NULL);
398 	parsed->label = g_strdup (label);
399 }
400 
401 static GcrParsed *
push_parsed(GcrParser * self,gboolean sensitive)402 push_parsed (GcrParser *self,
403              gboolean sensitive)
404 {
405 	GcrParsed *parsed = g_new0 (GcrParsed, 1);
406 	parsed->refs = 0;
407 	parsed->sensitive = sensitive;
408 	parsed->next = self->pv->parsed;
409 	parsed->filename = g_strdup (gcr_parser_get_filename (self));
410 	self->pv->parsed = parsed;
411 	return parsed;
412 }
413 
414 static void
_gcr_parsed_free(GcrParsed * parsed)415 _gcr_parsed_free (GcrParsed *parsed)
416 {
417 	gck_builder_clear (&parsed->builder);
418 	if (parsed->attrs)
419 		gck_attributes_unref (parsed->attrs);
420 	if (parsed->data)
421 		g_bytes_unref (parsed->data);
422 	g_free (parsed->label);
423 	g_free (parsed->filename);
424 	g_free (parsed);
425 }
426 
427 static void
pop_parsed(GcrParser * self,GcrParsed * parsed)428 pop_parsed (GcrParser *self,
429             GcrParsed *parsed)
430 {
431 	g_assert (parsed == self->pv->parsed);
432 	self->pv->parsed = parsed->next;
433 	_gcr_parsed_free (parsed);
434 }
435 
436 static gint
enum_next_password(GcrParser * self,PasswordState * state,const gchar ** password)437 enum_next_password (GcrParser *self, PasswordState *state, const gchar **password)
438 {
439 	gboolean result;
440 
441 	/*
442 	 * Next passes we look through all the passwords that the parser
443 	 * has seen so far. This is because different parts of a encrypted
444 	 * container (such as PKCS#12) often use the same password even
445 	 * if with different algorithms.
446 	 *
447 	 * If we didn't do this and the user chooses enters a password,
448 	 * but doesn't save it, they would get prompted for the same thing
449 	 * over and over, dumb.
450 	 */
451 
452 	/* Look in our list of passwords */
453 	if (state->seen < self->pv->passwords->len) {
454 		g_assert (state->seen >= 0);
455 		*password = g_ptr_array_index (self->pv->passwords, state->seen);
456 		++state->seen;
457 		return SUCCESS;
458 	}
459 
460 	/* Fire off all the parsed property signals so anyone watching can update their state */
461 	g_object_notify (G_OBJECT (self), "parsed-description");
462 	g_object_notify (G_OBJECT (self), "parsed-attributes");
463 	g_object_notify (G_OBJECT (self), "parsed-label");
464 
465 	g_signal_emit (self, signals[AUTHENTICATE], 0, state->ask_state, &result);
466 	++state->ask_state;
467 
468 	if (!result)
469 		return GCR_ERROR_CANCELLED;
470 
471 	/* Return any passwords added */
472 	if (state->seen < self->pv->passwords->len) {
473 		g_assert (state->seen >= 0);
474 		*password = g_ptr_array_index (self->pv->passwords, state->seen);
475 		++state->seen;
476 		return SUCCESS;
477 	}
478 
479 	return GCR_ERROR_LOCKED;
480 }
481 
482 static void
parsed_fire(GcrParser * self,GcrParsed * parsed)483 parsed_fire (GcrParser *self,
484              GcrParsed *parsed)
485 {
486 	g_assert (GCR_IS_PARSER (self));
487 	g_assert (parsed != NULL);
488 	g_assert (parsed == self->pv->parsed);
489 	g_assert (parsed->attrs == NULL);
490 
491 	parsed->attrs = gck_attributes_ref_sink (gck_builder_end (&parsed->builder));
492 
493 	g_object_notify (G_OBJECT (self), "parsed-description");
494 	g_object_notify (G_OBJECT (self), "parsed-attributes");
495 	g_object_notify (G_OBJECT (self), "parsed-label");
496 
497 	g_signal_emit (self, signals[PARSED], 0);
498 }
499 
500 /* -----------------------------------------------------------------------------
501  * RSA PRIVATE KEY
502  */
503 
504 static gint
parse_der_private_key_rsa(GcrParser * self,GBytes * data)505 parse_der_private_key_rsa (GcrParser *self,
506                            GBytes *data)
507 {
508 	gint res = GCR_ERROR_UNRECOGNIZED;
509 	GNode *asn = NULL;
510 	gulong version;
511 	GcrParsed *parsed;
512 
513 	parsed = push_parsed (self, TRUE);
514 
515 	asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPrivateKey", data);
516 	if (!asn)
517 		goto done;
518 
519 	parsing_block (parsed, GCR_FORMAT_DER_PRIVATE_KEY_RSA, data);
520 	parsing_object (parsed, CKO_PRIVATE_KEY);
521 	parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_RSA);
522 	parsed_boolean_attribute (parsed, CKA_PRIVATE, CK_TRUE);
523 	res = GCR_ERROR_FAILURE;
524 
525 	if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), &version))
526 		goto done;
527 
528 	/* We only support simple version */
529 	if (version != 0) {
530 		res = GCR_ERROR_UNRECOGNIZED;
531 		g_message ("unsupported version of RSA key: %lu", version);
532 		goto done;
533 	}
534 
535 	if (!parsed_asn1_number (parsed, asn, "modulus", CKA_MODULUS) ||
536 	    !parsed_asn1_number (parsed, asn, "publicExponent", CKA_PUBLIC_EXPONENT) ||
537 	    !parsed_asn1_number (parsed, asn, "privateExponent", CKA_PRIVATE_EXPONENT) ||
538 	    !parsed_asn1_number (parsed, asn, "prime1", CKA_PRIME_1) ||
539 	    !parsed_asn1_number (parsed, asn, "prime2", CKA_PRIME_2) ||
540 	    !parsed_asn1_number (parsed, asn, "coefficient", CKA_COEFFICIENT))
541 		goto done;
542 
543 	parsed_fire (self, parsed);
544 	res = SUCCESS;
545 
546 done:
547 	egg_asn1x_destroy (asn);
548 	if (res == GCR_ERROR_FAILURE)
549 		g_message ("invalid RSA key");
550 
551 	pop_parsed (self, parsed);
552 	return res;
553 }
554 
555 /* -----------------------------------------------------------------------------
556  * DSA PRIVATE KEY
557  */
558 
559 static gint
parse_der_private_key_dsa(GcrParser * self,GBytes * data)560 parse_der_private_key_dsa (GcrParser *self,
561                            GBytes *data)
562 {
563 	gint ret = GCR_ERROR_UNRECOGNIZED;
564 	GNode *asn = NULL;
565 	GcrParsed *parsed;
566 
567 	parsed = push_parsed (self, TRUE);
568 
569 	asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivateKey", data);
570 	if (!asn)
571 		goto done;
572 
573 	parsing_block (parsed, GCR_FORMAT_DER_PRIVATE_KEY_DSA, data);
574 	parsing_object (parsed, CKO_PRIVATE_KEY);
575 	parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_DSA);
576 	parsed_boolean_attribute (parsed, CKA_PRIVATE, CK_TRUE);
577 	ret = GCR_ERROR_FAILURE;
578 
579 	if (!parsed_asn1_number (parsed, asn, "p", CKA_PRIME) ||
580 	    !parsed_asn1_number (parsed, asn, "q", CKA_SUBPRIME) ||
581 	    !parsed_asn1_number (parsed, asn, "g", CKA_BASE) ||
582 	    !parsed_asn1_number (parsed, asn, "priv", CKA_VALUE))
583 		goto done;
584 
585 	parsed_fire (self, parsed);
586 	ret = SUCCESS;
587 
588 done:
589 	egg_asn1x_destroy (asn);
590 	if (ret == GCR_ERROR_FAILURE)
591 		g_message ("invalid DSA key");
592 
593 	pop_parsed (self, parsed);
594 	return ret;
595 }
596 
597 static gint
parse_der_private_key_dsa_parts(GcrParser * self,GBytes * keydata,GNode * params)598 parse_der_private_key_dsa_parts (GcrParser *self,
599                                  GBytes *keydata,
600                                  GNode *params)
601 {
602 	gint ret = GCR_ERROR_UNRECOGNIZED;
603 	GNode *asn_params = NULL;
604 	GNode *asn_key = NULL;
605 	GcrParsed *parsed;
606 
607 	parsed = push_parsed (self, TRUE);
608 
609 	asn_params = egg_asn1x_get_any_as (params, pk_asn1_tab, "DSAParameters");
610 	asn_key = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivatePart", keydata);
611 	if (!asn_params || !asn_key)
612 		goto done;
613 
614 	parsing_object (parsed, CKO_PRIVATE_KEY);
615 	parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_DSA);
616 	parsed_boolean_attribute (parsed, CKA_PRIVATE, CK_TRUE);
617 	ret = GCR_ERROR_FAILURE;
618 
619 	if (!parsed_asn1_number (parsed, asn_params, "p", CKA_PRIME) ||
620 	    !parsed_asn1_number (parsed, asn_params, "q", CKA_SUBPRIME) ||
621 	    !parsed_asn1_number (parsed, asn_params, "g", CKA_BASE) ||
622 	    !parsed_asn1_number (parsed, asn_key, NULL, CKA_VALUE))
623 		goto done;
624 
625 	parsed_fire (self, parsed);
626 	ret = SUCCESS;
627 
628 done:
629 	egg_asn1x_destroy (asn_key);
630 	egg_asn1x_destroy (asn_params);
631 	if (ret == GCR_ERROR_FAILURE)
632 		g_message ("invalid DSA key");
633 
634 	pop_parsed (self, parsed);
635 	return ret;
636 }
637 /* -----------------------------------------------------------------------------
638  * EC PRIVATE KEY
639  */
640 
641 static gint
parse_der_private_key_ec(GcrParser * self,GBytes * data)642 parse_der_private_key_ec (GcrParser *self,
643                           GBytes *data)
644 {
645 	gint ret = GCR_ERROR_UNRECOGNIZED;
646 	GNode *asn = NULL;
647 	GBytes *value = NULL;
648 	GBytes *pub = NULL;
649 	GNode *asn_q = NULL;
650 	GcrParsed *parsed;
651 	guint bits;
652 	gulong version;
653 
654 	parsed = push_parsed (self, TRUE);
655 
656 	asn = egg_asn1x_create_and_decode (pk_asn1_tab, "ECPrivateKey", data);
657 	if (!asn)
658 		goto done;
659 
660 	if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), &version))
661 		goto done;
662 
663 	/* We only support simple version */
664 	if (version != 1) {
665 		g_message ("unsupported version of EC key: %lu", version);
666 		goto done;
667 	}
668 
669 	parsing_block (parsed, GCR_FORMAT_DER_PRIVATE_KEY_EC, data);
670 	parsing_object (parsed, CKO_PRIVATE_KEY);
671 	parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_EC);
672 	parsed_boolean_attribute (parsed, CKA_PRIVATE, CK_TRUE);
673 	ret = GCR_ERROR_FAILURE;
674 
675 	if (!parsed_asn1_element (parsed, asn, "parameters", CKA_EC_PARAMS))
676 		goto done;
677 
678 	value = egg_asn1x_get_string_as_usg (egg_asn1x_node (asn, "privateKey", NULL), egg_secure_realloc);
679 	if (!value)
680 		goto done;
681 
682 	parsed_attribute_bytes (parsed, CKA_VALUE, value);
683 
684 	pub = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "publicKey", NULL), &bits);
685 	if (!pub || bits != 8 * g_bytes_get_size (pub))
686 		goto done;
687 	asn_q = egg_asn1x_create (pk_asn1_tab, "ECPoint");
688 	if (!asn_q)
689 		goto done;
690 	egg_asn1x_set_string_as_bytes (asn_q, pub);
691 
692 	if (!parsed_asn1_structure (parsed, asn_q, CKA_EC_POINT))
693 		goto done;
694 
695 	parsed_fire (self, parsed);
696 	ret = SUCCESS;
697 
698 done:
699 	if (pub)
700 		g_bytes_unref (pub);
701 	if (value)
702 		g_bytes_unref (value);
703 	egg_asn1x_destroy (asn);
704 	egg_asn1x_destroy (asn_q);
705 	if (ret == GCR_ERROR_FAILURE)
706 		g_message ("invalid EC key");
707 
708 	pop_parsed (self, parsed);
709 	return ret;
710 }
711 
712 /* -----------------------------------------------------------------------------
713  * PRIVATE KEY
714  */
715 
716 static gint
parse_der_private_key(GcrParser * self,GBytes * data)717 parse_der_private_key (GcrParser *self,
718                        GBytes *data)
719 {
720 	gint res;
721 
722 	res = parse_der_private_key_rsa (self, data);
723 	if (res == GCR_ERROR_UNRECOGNIZED)
724 		res = parse_der_private_key_dsa (self, data);
725 	if (res == GCR_ERROR_UNRECOGNIZED)
726 		res = parse_der_private_key_ec (self, data);
727 
728 	return res;
729 }
730 
731 /* -----------------------------------------------------------------------------
732  * SUBJECT PUBLIC KEY
733  */
734 
735 static gint
handle_subject_public_key_rsa(GcrParser * self,GcrParsed * parsed,GBytes * key,GNode * params)736 handle_subject_public_key_rsa (GcrParser *self,
737                                GcrParsed *parsed,
738                                GBytes *key,
739                                GNode *params)
740 {
741 	gint res = GCR_ERROR_FAILURE;
742 	GNode *asn = NULL;
743 
744 	asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPublicKey", key);
745 	if (!asn)
746 		goto done;
747 
748 	parsing_object (parsed, CKO_PUBLIC_KEY);
749 	parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_RSA);
750 
751 	if (!parsed_asn1_number (parsed, asn, "modulus", CKA_MODULUS) ||
752 	    !parsed_asn1_number (parsed, asn, "publicExponent", CKA_PUBLIC_EXPONENT))
753 		goto done;
754 
755 	res = SUCCESS;
756 
757 done:
758 	egg_asn1x_destroy (asn);
759 	return res;
760 }
761 
762 static gint
handle_subject_public_key_dsa(GcrParser * self,GcrParsed * parsed,GBytes * key,GNode * params)763 handle_subject_public_key_dsa (GcrParser *self,
764                                GcrParsed *parsed,
765                                GBytes *key,
766                                GNode *params)
767 {
768 	gint res = GCR_ERROR_FAILURE;
769 	GNode *key_asn = NULL;
770 	GNode *param_asn = NULL;
771 
772 	key_asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPublicPart", key);
773 	param_asn = egg_asn1x_get_any_as (params, pk_asn1_tab, "DSAParameters");
774 
775 	if (!key_asn || !param_asn)
776 		goto done;
777 
778 	parsing_object (parsed, CKO_PUBLIC_KEY);
779 	parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_DSA);
780 
781 	if (!parsed_asn1_number (parsed, param_asn, "p", CKA_PRIME) ||
782 	    !parsed_asn1_number (parsed, param_asn, "q", CKA_SUBPRIME) ||
783 	    !parsed_asn1_number (parsed, param_asn, "g", CKA_BASE) ||
784 	    !parsed_asn1_number (parsed, key_asn, NULL, CKA_VALUE))
785 		goto done;
786 
787 	res = SUCCESS;
788 
789 done:
790 	egg_asn1x_destroy (key_asn);
791 	egg_asn1x_destroy (param_asn);
792 	return res;
793 }
794 
795 static gint
handle_subject_public_key_ec(GcrParser * self,GcrParsed * parsed,GBytes * key,GNode * params)796 handle_subject_public_key_ec (GcrParser *self,
797                               GcrParsed *parsed,
798                               GBytes *key,
799                               GNode *params)
800 {
801 	gint ret = GCR_ERROR_FAILURE;
802 	GBytes *bytes = NULL;
803 	GNode *asn = NULL;
804 
805 	parsing_object (parsed, CKO_PUBLIC_KEY);
806 	parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_EC);
807 
808 	bytes = egg_asn1x_encode (params, g_realloc);
809 	parsed_attribute_bytes (parsed, CKA_EC_PARAMS, bytes);
810 	g_bytes_unref (bytes);
811 
812 	asn = egg_asn1x_create (pk_asn1_tab, "ECPoint");
813 	if (!asn)
814 		goto done;
815 	egg_asn1x_set_string_as_bytes (asn, key);
816 	parsed_asn1_structure (parsed, asn, CKA_EC_POINT);
817 	ret = SUCCESS;
818 done:
819 	egg_asn1x_destroy (asn);
820 	return ret;
821 }
822 
823 static gint
parse_der_subject_public_key(GcrParser * self,GBytes * data)824 parse_der_subject_public_key (GcrParser *self,
825                               GBytes *data)
826 {
827 	GcrParsed *parsed;
828 	GNode *params;
829 	GBytes *key;
830 	GNode *asn = NULL;
831 	GNode *node;
832 	GQuark oid;
833 	guint bits;
834 	gint ret;
835 
836 	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectPublicKeyInfo", data);
837 	if (asn == NULL)
838 		return GCR_ERROR_UNRECOGNIZED;
839 
840 	parsed = push_parsed (self, TRUE);
841 	parsing_block (parsed, GCR_FORMAT_DER_SUBJECT_PUBLIC_KEY, data);
842 
843 	node = egg_asn1x_node (asn, "algorithm", "algorithm", NULL);
844 	oid = egg_asn1x_get_oid_as_quark (node);
845 
846 	params = egg_asn1x_node (asn, "algorithm", "parameters", NULL);
847 
848 	node = egg_asn1x_node (asn, "subjectPublicKey", NULL);
849 	key = egg_asn1x_get_bits_as_raw (node, &bits);
850 
851 	if (oid == GCR_OID_PKIX1_RSA)
852 		ret = handle_subject_public_key_rsa (self, parsed, key, params);
853 
854 	else if (oid == GCR_OID_PKIX1_DSA)
855 		ret = handle_subject_public_key_dsa (self, parsed, key, params);
856 
857 	else if (oid == GCR_OID_PKIX1_EC)
858 		ret = handle_subject_public_key_ec (self, parsed, key, params);
859 
860 	else
861 		ret = GCR_ERROR_UNRECOGNIZED;
862 
863 	g_bytes_unref (key);
864 
865 	if (ret == SUCCESS)
866 		parsed_fire (self, parsed);
867 
868 	pop_parsed (self, parsed);
869 
870 	egg_asn1x_destroy (asn);
871 	return ret;
872 }
873 
874 /* -----------------------------------------------------------------------------
875  * PKCS8
876  */
877 
878 static gint
parse_der_pkcs8_plain(GcrParser * self,GBytes * data)879 parse_der_pkcs8_plain (GcrParser *self,
880                        GBytes *data)
881 {
882 	gint ret;
883 	CK_KEY_TYPE key_type;
884 	GQuark key_algo;
885 	GBytes *keydata = NULL;
886 	GNode *params = NULL;
887 	GNode *asn = NULL;
888 	GcrParsed *parsed;
889 
890 	parsed = push_parsed (self, TRUE);
891 	ret = GCR_ERROR_UNRECOGNIZED;
892 
893 	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo", data);
894 	if (!asn)
895 		goto done;
896 
897 	parsing_block (parsed, GCR_FORMAT_DER_PKCS8_PLAIN, data);
898 	ret = GCR_ERROR_FAILURE;
899 	key_type = GCK_INVALID;
900 
901 	key_algo = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "privateKeyAlgorithm", "algorithm", NULL));
902 	if (!key_algo)
903 		goto done;
904 	else if (key_algo == GCR_OID_PKIX1_RSA)
905 		key_type = CKK_RSA;
906 	else if (key_algo == GCR_OID_PKIX1_DSA)
907 		key_type = CKK_DSA;
908 	else if (key_algo == GCR_OID_PKIX1_EC)
909 		key_type = CKK_EC;
910 
911 	if (key_type == GCK_INVALID) {
912   		ret = GCR_ERROR_UNRECOGNIZED;
913   		goto done;
914   	}
915 
916 	keydata = egg_asn1x_get_string_as_bytes (egg_asn1x_node (asn, "privateKey", NULL));
917 	if (!keydata)
918 		goto done;
919 
920 	params = egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL);
921 
922 	ret = SUCCESS;
923 
924 done:
925 	if (ret == SUCCESS) {
926 		switch (key_type) {
927 		case CKK_RSA:
928 			ret = parse_der_private_key_rsa (self, keydata);
929 			break;
930 		case CKK_DSA:
931 			/* Try the normal sane format */
932 			ret = parse_der_private_key_dsa (self, keydata);
933 
934 			/* Otherwise try the two part format that everyone seems to like */
935 			if (ret == GCR_ERROR_UNRECOGNIZED && params)
936 				ret = parse_der_private_key_dsa_parts (self, keydata, params);
937 			break;
938 		case CKK_EC:
939 			ret = parse_der_private_key_ec (self, keydata);
940 			break;
941 
942 		default:
943 			g_message ("invalid or unsupported key type in PKCS#8 key");
944 			ret = GCR_ERROR_UNRECOGNIZED;
945 			break;
946 		};
947 
948 	} else if (ret == GCR_ERROR_FAILURE) {
949 		g_message ("invalid PKCS#8 key");
950 	}
951 
952 	if (keydata)
953 		g_bytes_unref (keydata);
954 	egg_asn1x_destroy (asn);
955 	pop_parsed (self, parsed);
956 	return ret;
957 }
958 
959 static gint
parse_der_pkcs8_encrypted(GcrParser * self,GBytes * data)960 parse_der_pkcs8_encrypted (GcrParser *self,
961                            GBytes *data)
962 {
963 	PasswordState pstate = PASSWORD_STATE_INIT;
964 	GNode *asn = NULL;
965 	gcry_cipher_hd_t cih = NULL;
966 	gcry_error_t gcry;
967 	gint ret, r;
968 	GQuark scheme;
969 	guchar *crypted = NULL;
970 	GNode *params = NULL;
971 	GBytes *cbytes;
972 	gsize n_crypted;
973 	const gchar *password;
974 	GcrParsed *parsed;
975 	gint l;
976 
977 	parsed = push_parsed (self, FALSE);
978 	ret = GCR_ERROR_UNRECOGNIZED;
979 
980 	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data);
981 	if (!asn)
982 		goto done;
983 
984 	parsing_block (parsed, GCR_FORMAT_DER_PKCS8_ENCRYPTED, data);
985 	ret = GCR_ERROR_FAILURE;
986 
987 	/* Figure out the type of encryption */
988 	scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptionAlgorithm", "algorithm", NULL));
989 	if (!scheme)
990 		goto done;
991 
992 	params = egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL);
993 
994 	/* Loop to try different passwords */
995 	for (;;) {
996 
997 		g_assert (cih == NULL);
998 
999 		r = enum_next_password (self, &pstate, &password);
1000 		if (r != SUCCESS) {
1001 			ret = r;
1002 			break;
1003 		}
1004 
1005 		/* Parse the encryption stuff into a cipher. */
1006 		if (!egg_symkey_read_cipher (scheme, password, -1, params, &cih))
1007 			break;
1008 
1009 		crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL), egg_secure_realloc, &n_crypted);
1010 		if (!crypted)
1011 			break;
1012 
1013 		gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
1014 		gcry_cipher_close (cih);
1015 		cih = NULL;
1016 
1017 		if (gcry != 0) {
1018 			g_warning ("couldn't decrypt pkcs8 data: %s", gcry_strerror (gcry));
1019 			break;
1020 		}
1021 
1022 		/* Unpad the DER data */
1023 		l = egg_asn1x_element_length (crypted, n_crypted);
1024 		if (l > 0)
1025 			n_crypted = l;
1026 
1027 		cbytes = g_bytes_new_with_free_func (crypted, n_crypted,
1028 		                                       egg_secure_free, crypted);
1029 		crypted = NULL;
1030 
1031 		/* Try to parse the resulting key */
1032 		r = parse_der_pkcs8_plain (self, cbytes);
1033 		g_bytes_unref (cbytes);
1034 
1035 		if (r != GCR_ERROR_UNRECOGNIZED) {
1036 			ret = r;
1037 			break;
1038 		}
1039 
1040 		/* We assume unrecognized data, is a bad encryption key */
1041 	}
1042 
1043 done:
1044 	if (cih)
1045 		gcry_cipher_close (cih);
1046 	egg_asn1x_destroy (asn);
1047 	egg_secure_free (crypted);
1048 
1049 	pop_parsed (self, parsed);
1050 	return ret;
1051 }
1052 
1053 static gint
parse_der_pkcs8(GcrParser * self,GBytes * data)1054 parse_der_pkcs8 (GcrParser *self,
1055                  GBytes *data)
1056 {
1057 	gint ret;
1058 
1059 	ret = parse_der_pkcs8_plain (self, data);
1060 	if (ret == GCR_ERROR_UNRECOGNIZED)
1061 		ret = parse_der_pkcs8_encrypted (self, data);
1062 
1063 	return ret;
1064 }
1065 
1066 /* -----------------------------------------------------------------------------
1067  * CERTIFICATE
1068  */
1069 
1070 static gint
parse_der_certificate(GcrParser * self,GBytes * data)1071 parse_der_certificate (GcrParser *self,
1072                        GBytes *data)
1073 {
1074 	gchar *name = NULL;
1075 	GcrParsed *parsed;
1076 	GNode *node;
1077 	GNode *asn;
1078 
1079 	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data);
1080 	if (asn == NULL)
1081 		return GCR_ERROR_UNRECOGNIZED;
1082 
1083 	parsed = push_parsed (self, FALSE);
1084 
1085 	parsing_block (parsed, GCR_FORMAT_DER_CERTIFICATE_X509, data);
1086 	parsing_object (parsed, CKO_CERTIFICATE);
1087 	parsed_ulong_attribute (parsed, CKA_CERTIFICATE_TYPE, CKC_X_509);
1088 
1089 	node = egg_asn1x_node (asn, "tbsCertificate", NULL);
1090 	g_return_val_if_fail (node != NULL, GCR_ERROR_FAILURE);
1091 
1092 	if (gcr_parser_get_parsed_label (self) == NULL)
1093 		name = egg_dn_read_part (egg_asn1x_node (node, "subject", "rdnSequence", NULL), "CN");
1094 
1095 	if (name != NULL) {
1096 		parsed_label (parsed, name);
1097 		g_free (name);
1098 	}
1099 
1100 	parsed_attribute_bytes (parsed, CKA_VALUE, data);
1101 	parsed_asn1_element (parsed, node, "subject", CKA_SUBJECT);
1102 	parsed_asn1_element (parsed, node, "issuer", CKA_ISSUER);
1103 	parsed_asn1_number (parsed, node, "serialNumber", CKA_SERIAL_NUMBER);
1104 	parsed_fire (self, parsed);
1105 
1106 	egg_asn1x_destroy (asn);
1107 
1108 	pop_parsed (self, parsed);
1109 	return SUCCESS;
1110 }
1111 
1112 /* -----------------------------------------------------------------------------
1113  * PKCS7
1114  */
1115 
1116 static gint
handle_pkcs7_signed_data(GcrParser * self,GNode * content)1117 handle_pkcs7_signed_data (GcrParser *self,
1118                           GNode *content)
1119 {
1120 	GNode *asn = NULL;
1121 	GNode *node;
1122 	gint ret;
1123 	GBytes *certificate;
1124 	int i;
1125 
1126 	ret = GCR_ERROR_UNRECOGNIZED;
1127 
1128 	asn = egg_asn1x_get_any_as (content, pkix_asn1_tab, "pkcs-7-SignedData");
1129 	if (!asn)
1130 		goto done;
1131 
1132 	for (i = 0; TRUE; ++i) {
1133 
1134 		node = egg_asn1x_node (asn, "certificates", i + 1, NULL);
1135 
1136 		/* No more certificates? */
1137 		if (node == NULL)
1138 			break;
1139 
1140 		certificate = egg_asn1x_get_element_raw (node);
1141 		ret = parse_der_certificate (self, certificate);
1142 		g_bytes_unref (certificate);
1143 
1144 		if (ret != SUCCESS)
1145 			goto done;
1146 	}
1147 
1148 	/* TODO: Parse out all the CRLs */
1149 
1150 	ret = SUCCESS;
1151 
1152 done:
1153 	egg_asn1x_destroy (asn);
1154 	return ret;
1155 }
1156 
1157 static gint
parse_der_pkcs7(GcrParser * self,GBytes * data)1158 parse_der_pkcs7 (GcrParser *self,
1159                  GBytes *data)
1160 {
1161 	GNode *asn = NULL;
1162 	GNode *node;
1163 	gint ret;
1164 	GNode *content = NULL;
1165 	GQuark oid;
1166 	GcrParsed *parsed;
1167 
1168 	parsed = push_parsed (self, FALSE);
1169 	ret = GCR_ERROR_UNRECOGNIZED;
1170 
1171 	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-ContentInfo", data);
1172 	if (!asn)
1173 		goto done;
1174 
1175 	parsing_block (parsed, GCR_FORMAT_DER_PKCS7, data);
1176 	ret = GCR_ERROR_FAILURE;
1177 
1178 	node = egg_asn1x_node (asn, "contentType", NULL);
1179 	if (!node)
1180 		goto done;
1181 
1182 	oid = egg_asn1x_get_oid_as_quark (node);
1183 	g_return_val_if_fail (oid, GCR_ERROR_FAILURE);
1184 
1185 	/* Outer most one must just be plain data */
1186 	if (oid != GCR_OID_PKCS7_SIGNED_DATA) {
1187 		g_message ("unsupported outer content type in pkcs7: %s", g_quark_to_string (oid));
1188 		goto done;
1189 	}
1190 
1191 	content = egg_asn1x_node (asn, "content", NULL);
1192 	if (!content)
1193 		goto done;
1194 
1195 	ret = handle_pkcs7_signed_data (self, content);
1196 
1197 done:
1198 	egg_asn1x_destroy (asn);
1199 	pop_parsed (self, parsed);
1200 	return ret;
1201 }
1202 
1203 /* -----------------------------------------------------------------------------
1204  * PKCS12
1205  */
1206 
1207 static gint
handle_pkcs12_cert_bag(GcrParser * self,GBytes * data)1208 handle_pkcs12_cert_bag (GcrParser *self,
1209                         GBytes *data)
1210 {
1211 	GNode *asn = NULL;
1212 	GNode *asn_content = NULL;
1213 	guchar *certificate = NULL;
1214 	GNode *element = NULL;
1215 	gsize n_certificate;
1216 	GBytes *bytes;
1217 	gint ret;
1218 
1219 	ret = GCR_ERROR_UNRECOGNIZED;
1220 	asn = egg_asn1x_create_and_decode_full (pkix_asn1_tab, "pkcs-12-CertBag",
1221 	                                        data, EGG_ASN1X_NO_STRICT);
1222 	if (!asn)
1223 		goto done;
1224 
1225 	ret = GCR_ERROR_FAILURE;
1226 
1227 	element = egg_asn1x_node (asn, "certValue", NULL);
1228 	if (!element)
1229 		goto done;
1230 
1231 	asn_content = egg_asn1x_get_any_as (element, pkix_asn1_tab, "pkcs-7-Data");
1232 	if (!asn_content)
1233 		goto done;
1234 
1235 	certificate = egg_asn1x_get_string_as_raw (asn_content, NULL, &n_certificate);
1236 	if (!certificate)
1237 		goto done;
1238 
1239 	bytes = g_bytes_new_take (certificate, n_certificate);
1240 	ret = parse_der_certificate (self, bytes);
1241 	g_bytes_unref (bytes);
1242 
1243 done:
1244 	egg_asn1x_destroy (asn_content);
1245 	egg_asn1x_destroy (asn);
1246 	return ret;
1247 }
1248 
1249 static gchar *
parse_pkcs12_bag_friendly_name(GNode * asn)1250 parse_pkcs12_bag_friendly_name (GNode *asn)
1251 {
1252 	guint count, i;
1253 	GQuark oid;
1254 	GNode *node;
1255 	GNode *asn_str;
1256 	gchar *result;
1257 
1258 	if (asn == NULL)
1259 		return NULL;
1260 
1261 	count = egg_asn1x_count (asn);
1262 	for (i = 1; i <= count; i++) {
1263 		oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, i, "type", NULL));
1264 		if (oid == GCR_OID_PKCS9_ATTRIBUTE_FRIENDLY) {
1265 			node = egg_asn1x_node (asn, i, "values", 1, NULL);
1266 			if (node != NULL) {
1267 				asn_str = egg_asn1x_get_any_as_string (node, EGG_ASN1X_BMP_STRING);
1268 				if (asn_str) {
1269 					result = egg_asn1x_get_bmpstring_as_utf8 (asn_str);
1270 					egg_asn1x_destroy (asn_str);
1271 					return result;
1272 				}
1273 			}
1274 		}
1275 	}
1276 
1277 	return NULL;
1278 }
1279 
1280 static gint
handle_pkcs12_bag(GcrParser * self,GBytes * data)1281 handle_pkcs12_bag (GcrParser *self,
1282                    GBytes *data)
1283 {
1284 	GNode *asn = NULL;
1285 	gint ret, r;
1286 	guint count = 0;
1287 	GQuark oid;
1288 	GNode *value;
1289 	GBytes *element = NULL;
1290 	gchar *friendly;
1291 	guint i;
1292 	GcrParsed *parsed;
1293 
1294 	ret = GCR_ERROR_UNRECOGNIZED;
1295 
1296 	asn = egg_asn1x_create_and_decode_full (pkix_asn1_tab, "pkcs-12-SafeContents",
1297 	                                        data, EGG_ASN1X_NO_STRICT);
1298 	if (!asn)
1299 		goto done;
1300 
1301 	ret = GCR_ERROR_FAILURE;
1302 
1303 	/* Get the number of elements in this bag */
1304 	count = egg_asn1x_count (asn);
1305 
1306 	/*
1307 	 * Now inside each bag are multiple elements. Who comes up
1308 	 * with this stuff?
1309 	 */
1310 	for (i = 1; i <= count; i++) {
1311 
1312 		oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, i, "bagId", NULL));
1313 		if (!oid)
1314 			goto done;
1315 
1316 		value = egg_asn1x_node (asn, i, "bagValue", NULL);
1317 		if (!value)
1318 			goto done;
1319 
1320 		element = egg_asn1x_get_element_raw (value);
1321 		parsed = push_parsed (self, FALSE);
1322 
1323 		friendly = parse_pkcs12_bag_friendly_name (egg_asn1x_node (asn, i, "bagAttributes", NULL));
1324 		if (friendly != NULL) {
1325 			parsed_label (parsed, friendly);
1326 			g_free (friendly);
1327 		}
1328 
1329 		/* A normal unencrypted key */
1330 		if (oid == GCR_OID_PKCS12_BAG_PKCS8_KEY) {
1331 			r = parse_der_pkcs8_plain (self, element);
1332 
1333 		/* A properly encrypted key */
1334 		} else if (oid == GCR_OID_PKCS12_BAG_PKCS8_ENCRYPTED_KEY) {
1335 			r = parse_der_pkcs8_encrypted (self, element);
1336 
1337 		/* A certificate */
1338 		} else if (oid == GCR_OID_PKCS12_BAG_CERTIFICATE) {
1339 			r = handle_pkcs12_cert_bag (self, element);
1340 
1341 		/* TODO: GCR_OID_PKCS12_BAG_CRL */
1342 		} else {
1343 			r = GCR_ERROR_UNRECOGNIZED;
1344 		}
1345 
1346 		if (element != NULL)
1347 			g_bytes_unref (element);
1348 
1349 		pop_parsed (self, parsed);
1350 
1351 		if (r == GCR_ERROR_FAILURE ||
1352 		    r == GCR_ERROR_CANCELLED ||
1353 		    r == GCR_ERROR_LOCKED) {
1354 			ret = r;
1355 			goto done;
1356 		}
1357 	}
1358 
1359 	ret = SUCCESS;
1360 
1361 done:
1362 	egg_asn1x_destroy (asn);
1363 	return ret;
1364 }
1365 
1366 static gint
handle_pkcs12_encrypted_bag(GcrParser * self,GNode * bag)1367 handle_pkcs12_encrypted_bag (GcrParser *self,
1368                              GNode *bag)
1369 {
1370 	PasswordState pstate = PASSWORD_STATE_INIT;
1371 	GNode *asn = NULL;
1372 	gcry_cipher_hd_t cih = NULL;
1373 	gcry_error_t gcry;
1374 	guchar *crypted = NULL;
1375 	GNode *params = NULL;
1376 	gsize n_crypted;
1377 	const gchar *password;
1378 	GBytes *cbytes;
1379 	GQuark scheme;
1380 	gint ret, r;
1381 	gint l;
1382 
1383 	ret = GCR_ERROR_UNRECOGNIZED;
1384 
1385 	asn = egg_asn1x_get_any_as_full (bag, pkix_asn1_tab, "pkcs-7-EncryptedData",
1386 	                                 EGG_ASN1X_NO_STRICT);
1387 	if (!asn)
1388 		goto done;
1389 
1390 	ret = GCR_ERROR_FAILURE;
1391 
1392 	/* Check the encryption schema OID */
1393 	scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptedContentInfo", "contentEncryptionAlgorithm", "algorithm", NULL));
1394 	if (!scheme)
1395 		goto done;
1396 
1397 	params = egg_asn1x_node (asn, "encryptedContentInfo", "contentEncryptionAlgorithm", "parameters", NULL);
1398 	if (!params)
1399 		goto done;
1400 
1401 	/* Loop to try different passwords */
1402 	for (;;) {
1403 
1404 		g_assert (cih == NULL);
1405 
1406 		r = enum_next_password (self, &pstate, &password);
1407 		if (r != SUCCESS) {
1408 			ret = r;
1409 			goto done;
1410 		}
1411 
1412 		/* Parse the encryption stuff into a cipher. */
1413 		if (!egg_symkey_read_cipher (scheme, password, -1, params, &cih)) {
1414 			ret = GCR_ERROR_FAILURE;
1415 			goto done;
1416 		}
1417 
1418 		crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedContentInfo", "encryptedContent", NULL),
1419 		                                       egg_secure_realloc, &n_crypted);
1420 		if (!crypted)
1421 			goto done;
1422 
1423 		gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
1424 		gcry_cipher_close (cih);
1425 		cih = NULL;
1426 
1427 		if (gcry != 0) {
1428 			g_warning ("couldn't decrypt pkcs12 data: %s", gcry_strerror (gcry));
1429 			goto done;
1430 		}
1431 
1432 		/* Unpad the DER data */
1433 		l = egg_asn1x_element_length (crypted, n_crypted);
1434 		if (l > 0)
1435 			n_crypted = l;
1436 
1437 		cbytes = g_bytes_new_with_free_func (crypted, n_crypted, egg_secure_free, crypted);
1438 		crypted = NULL;
1439 
1440 		/* Try to parse the resulting key */
1441 		r = handle_pkcs12_bag (self, cbytes);
1442 		g_bytes_unref (cbytes);
1443 
1444 		if (r != GCR_ERROR_UNRECOGNIZED) {
1445 			ret = r;
1446 			break;
1447 		}
1448 
1449 		/* We assume unrecognized data is a bad encryption key */
1450 	}
1451 
1452 done:
1453 	if (cih)
1454 		gcry_cipher_close (cih);
1455 	egg_asn1x_destroy (asn);
1456 	egg_secure_free (crypted);
1457 	return ret;
1458 }
1459 
1460 static gint
handle_pkcs12_safe(GcrParser * self,GBytes * data)1461 handle_pkcs12_safe (GcrParser *self,
1462                     GBytes *data)
1463 {
1464 	GNode *asn = NULL;
1465 	GNode *asn_content = NULL;
1466 	gint ret, r;
1467 	GNode *bag;
1468 	GBytes *content;
1469 	GQuark oid;
1470 	guint i;
1471 	GNode *node;
1472 
1473 	ret = GCR_ERROR_UNRECOGNIZED;
1474 
1475 	asn = egg_asn1x_create_and_decode_full (pkix_asn1_tab, "pkcs-12-AuthenticatedSafe",
1476 	                                        data, EGG_ASN1X_NO_STRICT);
1477 	if (!asn)
1478 		goto done;
1479 
1480 	ret = GCR_ERROR_FAILURE;
1481 
1482 	/*
1483 	 * Inside each PKCS12 safe there are multiple bags.
1484 	 */
1485 	for (i = 0; TRUE; ++i) {
1486 		node = egg_asn1x_node (asn, i + 1, "contentType", NULL);
1487 
1488 		/* All done? no more bags */
1489 		if (!node)
1490 			break;
1491 
1492 		oid = egg_asn1x_get_oid_as_quark (node);
1493 
1494 		bag = egg_asn1x_node (asn, i + 1, "content", NULL);
1495 		if (!bag)
1496 			goto done;
1497 
1498 		/* A non encrypted bag, just parse */
1499 		if (oid == GCR_OID_PKCS7_DATA) {
1500 
1501 			egg_asn1x_destroy (asn_content);
1502 			asn_content = egg_asn1x_get_any_as_full (bag, pkix_asn1_tab,
1503 			                                         "pkcs-7-Data", EGG_ASN1X_NO_STRICT);
1504 			if (!asn_content)
1505 				goto done;
1506 
1507 			content = egg_asn1x_get_string_as_bytes (asn_content);
1508 			if (!content)
1509 				goto done;
1510 
1511 			r = handle_pkcs12_bag (self, content);
1512 			g_bytes_unref (content);
1513 
1514 		/* Encrypted data first needs decryption */
1515 		} else if (oid == GCR_OID_PKCS7_ENCRYPTED_DATA) {
1516 			r = handle_pkcs12_encrypted_bag (self, bag);
1517 
1518 		/* Hmmmm, not sure what this is */
1519 		} else {
1520 			g_warning ("unrecognized type of safe content in pkcs12: %s", g_quark_to_string (oid));
1521 			r = GCR_ERROR_UNRECOGNIZED;
1522 		}
1523 
1524 		if (r == GCR_ERROR_FAILURE ||
1525 		    r == GCR_ERROR_CANCELLED ||
1526 		    r == GCR_ERROR_LOCKED) {
1527 			ret = r;
1528 			goto done;
1529 		}
1530 	}
1531 
1532 	ret = SUCCESS;
1533 
1534 done:
1535 	egg_asn1x_destroy (asn);
1536 	egg_asn1x_destroy (asn_content);
1537 	return ret;
1538 }
1539 
1540 static gint
verify_pkcs12_safe(GcrParser * self,GNode * asn,GBytes * content)1541 verify_pkcs12_safe (GcrParser *self,
1542                     GNode *asn,
1543                     GBytes *content)
1544 {
1545 	PasswordState pstate = PASSWORD_STATE_INIT;
1546 	const gchar *password;
1547 	gcry_md_hd_t mdh = NULL;
1548 	const guchar *mac_digest;
1549 	gsize mac_len;
1550 	guchar *digest = NULL;
1551 	gsize n_digest;
1552 	GQuark algorithm;
1553 	GNode *mac_data;
1554 	int ret, r;
1555 
1556 	ret = GCR_ERROR_FAILURE;
1557 
1558 	/*
1559 	 * The MAC is optional (and outside the encryption no less). I wonder
1560 	 * what the designers (ha) of PKCS#12 were trying to achieve
1561 	 */
1562 
1563 	mac_data = egg_asn1x_node (asn, "macData", NULL);
1564 	if (mac_data == NULL)
1565 		return SUCCESS;
1566 
1567 	algorithm = egg_asn1x_get_oid_as_quark (egg_asn1x_node (mac_data, "mac",
1568 	                                        "digestAlgorithm", "algorithm", NULL));
1569 	if (!algorithm)
1570 		goto done;
1571 
1572 	digest = egg_asn1x_get_string_as_raw (egg_asn1x_node (mac_data, "mac", "digest", NULL), NULL, &n_digest);
1573 	if (!digest)
1574 		goto done;
1575 
1576 	/* Loop to try different passwords */
1577 	for (;;) {
1578 		g_assert (mdh == NULL);
1579 
1580 		r = enum_next_password (self, &pstate, &password);
1581 		if (r != SUCCESS) {
1582 			ret = r;
1583 			goto done;
1584 		}
1585 
1586 		/* Parse the encryption stuff into a cipher. */
1587 		if (!egg_symkey_read_mac (algorithm, password, -1, mac_data, &mdh, &mac_len)) {
1588 			ret = GCR_ERROR_FAILURE;
1589 			goto done;
1590 		}
1591 
1592 		/* If not the right length, then that's really broken */
1593 		if (mac_len != n_digest) {
1594 			r = GCR_ERROR_FAILURE;
1595 
1596 		} else {
1597 			gcry_md_write (mdh, g_bytes_get_data (content, NULL), g_bytes_get_size (content));
1598 			mac_digest = gcry_md_read (mdh, 0);
1599 			g_return_val_if_fail (mac_digest, GCR_ERROR_FAILURE);
1600 			r = memcmp (mac_digest, digest, n_digest) == 0 ? SUCCESS : GCR_ERROR_LOCKED;
1601 		}
1602 
1603 		gcry_md_close (mdh);
1604 		mdh = NULL;
1605 
1606 		if (r != GCR_ERROR_LOCKED) {
1607 			ret = r;
1608 			break;
1609 		}
1610 	}
1611 
1612 done:
1613 	if (mdh)
1614 		gcry_md_close (mdh);
1615 	g_free (digest);
1616 	return ret;
1617 
1618 }
1619 
1620 static gint
parse_der_pkcs12(GcrParser * self,GBytes * data)1621 parse_der_pkcs12 (GcrParser *self,
1622                   GBytes *data)
1623 {
1624 	GNode *asn = NULL;
1625 	gint ret;
1626 	GNode *content = NULL;
1627 	GBytes *string = NULL;
1628 	GQuark oid;
1629 	GcrParsed *parsed;
1630 
1631 	parsed = push_parsed (self, FALSE);
1632 	ret = GCR_ERROR_UNRECOGNIZED;
1633 
1634 	/*
1635 	 * Because PKCS#12 files, the bags specifically, are notorious for
1636 	 * being crappily constructed and are often break rules such as DER
1637 	 * sorting order etc.. we parse the DER in a non-strict fashion.
1638 	 *
1639 	 * The rules in DER are designed for X.509 certificates, so there is
1640 	 * only one way to represent a given certificate (although they fail
1641 	 * at that as well). But with PKCS#12 we don't have such high
1642 	 * requirements, and we can slack off on our validation.
1643 	 */
1644 
1645 	asn = egg_asn1x_create_and_decode_full (pkix_asn1_tab, "pkcs-12-PFX",
1646 	                                        data, EGG_ASN1X_NO_STRICT);
1647 	if (!asn)
1648 		goto done;
1649 
1650 	parsing_block (parsed, GCR_FORMAT_DER_PKCS12, data);
1651 
1652 	oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "authSafe", "contentType", NULL));
1653 	if (!oid)
1654 		goto done;
1655 
1656 	/* Outer most one must just be plain data */
1657 	if (oid != GCR_OID_PKCS7_DATA) {
1658 		g_message ("unsupported safe content type in pkcs12: %s", g_quark_to_string (oid));
1659 		goto done;
1660 	}
1661 
1662 	content = egg_asn1x_get_any_as (egg_asn1x_node (asn, "authSafe", "content", NULL),
1663 	                                pkix_asn1_tab, "pkcs-7-Data");
1664 	if (!content)
1665 		goto done;
1666 
1667 	string = egg_asn1x_get_string_as_bytes (content);
1668 	if (!string)
1669 		goto done;
1670 
1671 	ret = verify_pkcs12_safe (self, asn, string);
1672 	if (ret == SUCCESS)
1673 		ret = handle_pkcs12_safe (self, string);
1674 
1675 done:
1676 	if (content)
1677 		egg_asn1x_destroy (content);
1678 	if (string)
1679 		g_bytes_unref (string);
1680 	egg_asn1x_destroy (asn);
1681 	pop_parsed (self, parsed);
1682 	return ret;
1683 }
1684 
1685 /* -----------------------------------------------------------------------------
1686  * CERTIFICATE REQUESTS
1687  */
1688 
1689 static gint
parse_der_pkcs10(GcrParser * self,GBytes * data)1690 parse_der_pkcs10 (GcrParser *self,
1691                   GBytes *data)
1692 {
1693 	GNode *asn = NULL;
1694 	GNode *node;
1695 	GcrParsed *parsed;
1696 	gchar *name = NULL;
1697 
1698 	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-10-CertificationRequest", data);
1699 	if (!asn)
1700 		return GCR_ERROR_UNRECOGNIZED;
1701 
1702 	parsed = push_parsed (self, FALSE);
1703 	parsing_block (parsed, GCR_FORMAT_DER_PKCS10, data);
1704 
1705 	parsing_object (parsed, CKO_GCR_CERTIFICATE_REQUEST);
1706 	parsed_ulong_attribute (parsed, CKA_GCR_CERTIFICATE_REQUEST_TYPE, CKQ_GCR_PKCS10);
1707 
1708 	node = egg_asn1x_node (asn, "certificationRequestInfo", NULL);
1709 	g_return_val_if_fail (node != NULL, GCR_ERROR_FAILURE);
1710 
1711 	if (gcr_parser_get_parsed_label (self) == NULL)
1712 		name = egg_dn_read_part (egg_asn1x_node (node, "subject", "rdnSequence", NULL), "CN");
1713 
1714 	if (name != NULL) {
1715 		parsed_label (parsed, name);
1716 		g_free (name);
1717 	}
1718 
1719 	parsed_attribute_bytes (parsed, CKA_VALUE, data);
1720 	parsed_asn1_element (parsed, node, "subject", CKA_SUBJECT);
1721 	parsed_fire (self, parsed);
1722 
1723 	egg_asn1x_destroy (asn);
1724 
1725 	pop_parsed (self, parsed);
1726 	return SUCCESS;
1727 }
1728 
1729 static gint
parse_der_spkac(GcrParser * self,GBytes * data)1730 parse_der_spkac (GcrParser *self,
1731                  GBytes *data)
1732 {
1733 	GNode *asn = NULL;
1734 	GcrParsed *parsed;
1735 
1736 	asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SignedPublicKeyAndChallenge", data);
1737 	if (!asn)
1738 		return GCR_ERROR_UNRECOGNIZED;
1739 
1740 	parsed = push_parsed (self, FALSE);
1741 	parsing_block (parsed, GCR_FORMAT_DER_SPKAC, data);
1742 
1743 	parsing_object (parsed, CKO_GCR_CERTIFICATE_REQUEST);
1744 	parsed_ulong_attribute (parsed, CKA_GCR_CERTIFICATE_REQUEST_TYPE, CKQ_GCR_SPKAC);
1745 
1746 	parsed_attribute_bytes (parsed, CKA_VALUE, data);
1747 	parsed_fire (self, parsed);
1748 
1749 	egg_asn1x_destroy (asn);
1750 
1751 	pop_parsed (self, parsed);
1752 	return SUCCESS;
1753 }
1754 
1755 static gint
parse_base64_spkac(GcrParser * self,GBytes * dat)1756 parse_base64_spkac (GcrParser *self,
1757                     GBytes *dat)
1758 {
1759 	const gchar *PREFIX = "SPKAC=";
1760 	const gsize PREFIX_LEN = 6;
1761 
1762 	GcrParsed *parsed;
1763 	guchar *spkac;
1764 	gsize n_spkac;
1765 	const guchar *data;
1766 	GBytes *bytes;
1767 	gsize n_data;
1768 	gint ret;
1769 	data = g_bytes_get_data (dat, &n_data);
1770 
1771 	if (n_data > PREFIX_LEN && memcmp (PREFIX, data, PREFIX_LEN))
1772 		return GCR_ERROR_UNRECOGNIZED;
1773 
1774 	parsed = push_parsed (self, FALSE);
1775 	parsing_block (parsed, GCR_FORMAT_DER_SPKAC, dat);
1776 
1777 	data += PREFIX_LEN;
1778 	n_data -= PREFIX_LEN;
1779 
1780 	spkac = g_base64_decode ((const gchar *)data, &n_spkac);
1781 	if (spkac != NULL) {
1782 		bytes = g_bytes_new_take (spkac, n_spkac);
1783 		ret = parse_der_spkac (self, bytes);
1784 		g_bytes_unref (bytes);
1785 	} else {
1786 		ret = GCR_ERROR_FAILURE;
1787 	}
1788 
1789 	pop_parsed (self, parsed);
1790 	return ret;
1791 }
1792 
1793 /* -----------------------------------------------------------------------------
1794  * OPENPGP
1795  */
1796 
1797 static void
on_openpgp_packet(GPtrArray * records,GBytes * outer,gpointer user_data)1798 on_openpgp_packet (GPtrArray *records,
1799                    GBytes *outer,
1800                    gpointer user_data)
1801 {
1802 	GcrParser *self = GCR_PARSER (user_data);
1803 	GcrParsed *parsed;
1804 	gchar *string;
1805 
1806 	/*
1807 	 * If it's an openpgp packet that doesn't contain a key, then
1808 	 * just ignore it here.
1809 	 */
1810 	if (records->len == 0)
1811 		return;
1812 
1813 	parsed = push_parsed (self, FALSE);
1814 
1815 	/* All we can do is the packet bounds */
1816 	parsing_block (parsed, GCR_FORMAT_OPENPGP_PACKET, outer);
1817 	parsing_object (parsed, CKO_GCR_GNUPG_RECORDS);
1818 	string = _gcr_records_format (records);
1819 	parsed_attribute (parsed, CKA_VALUE, string, strlen (string));
1820 	parsed_fire (self, parsed);
1821 	pop_parsed (self, parsed);
1822 
1823 	g_free (string);
1824 }
1825 
1826 static gint
parse_openpgp_packets(GcrParser * self,GBytes * data)1827 parse_openpgp_packets (GcrParser *self,
1828                        GBytes *data)
1829 {
1830 	gint num_parsed;
1831 
1832 	num_parsed = _gcr_openpgp_parse (data,
1833 	                                 GCR_OPENPGP_PARSE_KEYS |
1834 	                                 GCR_OPENPGP_PARSE_ATTRIBUTES |
1835 	                                 GCR_OPENPGP_PARSE_SIGNATURES,
1836 	                                 on_openpgp_packet, self);
1837 
1838 	if (num_parsed == 0)
1839 		return GCR_ERROR_UNRECOGNIZED;
1840 	return SUCCESS;
1841 }
1842 
1843 /* -----------------------------------------------------------------------------
1844  * ARMOR PARSING
1845  */
1846 
1847 static gboolean
formats_for_armor_type(GQuark armor_type,gint * inner_format,gint * outer_format)1848 formats_for_armor_type (GQuark armor_type,
1849                         gint *inner_format,
1850                         gint *outer_format)
1851 {
1852 	gint dummy;
1853 	if (!inner_format)
1854 		inner_format = &dummy;
1855 	if (!outer_format)
1856 		outer_format = &dummy;
1857 
1858 	if (armor_type == PEM_RSA_PRIVATE_KEY) {
1859 		*inner_format = GCR_FORMAT_DER_PRIVATE_KEY_RSA;
1860 		*outer_format = GCR_FORMAT_PEM_PRIVATE_KEY_RSA;
1861 	} else if (armor_type == PEM_DSA_PRIVATE_KEY) {
1862 		*inner_format = GCR_FORMAT_DER_PRIVATE_KEY_DSA;
1863 		*outer_format = GCR_FORMAT_PEM_PRIVATE_KEY_DSA;
1864 	} else if (armor_type == PEM_EC_PRIVATE_KEY) {
1865 		*inner_format = GCR_FORMAT_DER_PRIVATE_KEY_EC;
1866 		*outer_format = GCR_FORMAT_PEM_PRIVATE_KEY_EC;
1867 	} else if (armor_type == PEM_ANY_PRIVATE_KEY) {
1868 		*inner_format = GCR_FORMAT_DER_PRIVATE_KEY;
1869 		*outer_format = GCR_FORMAT_PEM_PRIVATE_KEY;
1870 	} else if (armor_type == PEM_PRIVATE_KEY) {
1871 		*inner_format = GCR_FORMAT_DER_PKCS8_PLAIN;
1872 		*outer_format = GCR_FORMAT_PEM_PKCS8_PLAIN;
1873 	} else if (armor_type == PEM_ENCRYPTED_PRIVATE_KEY) {
1874 		*inner_format = GCR_FORMAT_DER_PKCS8_ENCRYPTED;
1875 		*outer_format = GCR_FORMAT_PEM_PKCS8_ENCRYPTED;
1876 	} else if (armor_type == PEM_CERTIFICATE) {
1877 		*inner_format = GCR_FORMAT_DER_CERTIFICATE_X509;
1878 		*outer_format = GCR_FORMAT_PEM_CERTIFICATE_X509;
1879 	} else if (armor_type == PEM_PKCS7) {
1880 		*inner_format = GCR_FORMAT_DER_PKCS7;
1881 		*outer_format = GCR_FORMAT_PEM_PKCS7;
1882 	} else if (armor_type == PEM_CERTIFICATE_REQUEST) {
1883 		*inner_format = GCR_FORMAT_DER_PKCS10;
1884 		*outer_format = GCR_FORMAT_PEM_PKCS10;
1885 	} else if (armor_type == PEM_NEW_CERTIFICATE_REQUEST) {
1886 		*inner_format = GCR_FORMAT_DER_PKCS10;
1887 		*outer_format = GCR_FORMAT_PEM_PKCS10;
1888 	} else if (armor_type == PEM_PKCS12) {
1889 		*inner_format = GCR_FORMAT_DER_PKCS12;
1890 		*outer_format = GCR_FORMAT_PEM_PKCS12;
1891 	} else if (armor_type == PEM_PUBLIC_KEY) {
1892 		*inner_format = GCR_FORMAT_DER_SUBJECT_PUBLIC_KEY;
1893 		*outer_format = GCR_FORMAT_PEM_PUBLIC_KEY;
1894 	} else if (armor_type == ARMOR_PGP_PRIVATE_KEY_BLOCK) {
1895 		*inner_format = GCR_FORMAT_OPENPGP_PACKET;
1896 		*outer_format = GCR_FORMAT_OPENPGP_ARMOR;
1897 	} else if (armor_type == ARMOR_PGP_PUBLIC_KEY_BLOCK) {
1898 		*inner_format = GCR_FORMAT_OPENPGP_PACKET;
1899 		*outer_format = GCR_FORMAT_OPENPGP_ARMOR;
1900 	} else {
1901 		return FALSE;
1902 	}
1903 
1904 	return TRUE;
1905 }
1906 
1907 static gint
handle_plain_pem(GcrParser * self,gint format_id,gint want_format,GBytes * data)1908 handle_plain_pem (GcrParser *self,
1909                   gint format_id,
1910                   gint want_format,
1911                   GBytes *data)
1912 {
1913 	ParserFormat *format;
1914 
1915 	if (want_format != 0 && want_format != format_id)
1916 		return GCR_ERROR_UNRECOGNIZED;
1917 
1918 	format = parser_format_lookup (format_id);
1919 	if (format == NULL)
1920 		return GCR_ERROR_UNRECOGNIZED;
1921 
1922 	return (format->function) (self, data);
1923 }
1924 
1925 static gint
handle_encrypted_pem(GcrParser * self,gint format_id,gint want_format,GHashTable * headers,GBytes * data)1926 handle_encrypted_pem (GcrParser *self,
1927                       gint format_id,
1928                       gint want_format,
1929                       GHashTable *headers,
1930                       GBytes *data)
1931 {
1932 	PasswordState pstate = PASSWORD_STATE_INIT;
1933 	const gchar *password;
1934 	guchar *decrypted;
1935 	gsize n_decrypted;
1936 	const gchar *val;
1937 	GBytes *dbytes;
1938 	gint res;
1939 	gint l;
1940 
1941 	g_assert (GCR_IS_PARSER (self));
1942 	g_assert (headers);
1943 
1944 	val = g_hash_table_lookup (headers, "DEK-Info");
1945 	if (!val) {
1946 		g_message ("missing encryption header");
1947 		return GCR_ERROR_FAILURE;
1948 	}
1949 
1950 	for (;;) {
1951 
1952 		res = enum_next_password (self, &pstate, &password);
1953 		if (res != SUCCESS)
1954 			break;
1955 
1956 		/* Decrypt, this will result in garble if invalid password */
1957 		decrypted = egg_openssl_decrypt_block (val, password, -1, data, &n_decrypted);
1958 		if (!decrypted) {
1959 			res = GCR_ERROR_FAILURE;
1960 			break;
1961 		}
1962 
1963 		/* Unpad the DER data */
1964 		l = egg_asn1x_element_length (decrypted, n_decrypted);
1965 		if (l > 0)
1966 			n_decrypted = l;
1967 
1968 		dbytes = g_bytes_new_with_free_func (decrypted, n_decrypted,
1969 		                                       egg_secure_free, decrypted);
1970 		decrypted = NULL;
1971 
1972 		/* Try to parse */
1973 		res = handle_plain_pem (self, format_id, want_format, dbytes);
1974 		g_bytes_unref (dbytes);
1975 
1976 		/* Unrecognized is a bad password */
1977 		if (res != GCR_ERROR_UNRECOGNIZED)
1978 			break;
1979 	}
1980 
1981 	return res;
1982 }
1983 
1984 typedef struct {
1985 	GcrParser *parser;
1986 	gint result;
1987 	gint want_format;
1988 } HandlePemArgs;
1989 
1990 static void
handle_pem_data(GQuark type,GBytes * data,GBytes * outer,GHashTable * headers,gpointer user_data)1991 handle_pem_data (GQuark type,
1992                  GBytes *data,
1993                  GBytes *outer,
1994                  GHashTable *headers,
1995                  gpointer user_data)
1996 {
1997 	HandlePemArgs *args = (HandlePemArgs*)user_data;
1998 	gint res = GCR_ERROR_FAILURE;
1999 	gboolean encrypted = FALSE;
2000 	const gchar *val;
2001 	gint inner_format;
2002 	gint outer_format;
2003 	GcrParsed *parsed;
2004 
2005 	/* Something already failed to parse */
2006 	if (args->result == GCR_ERROR_FAILURE)
2007 		return;
2008 
2009 	if (!formats_for_armor_type (type, &inner_format, &outer_format))
2010 		return;
2011 
2012 	parsed = push_parsed (args->parser, FALSE);
2013 
2014 	/* Fill in information necessary for prompting */
2015 	parsing_block (parsed, outer_format, outer);
2016 
2017 	/* See if it's encrypted PEM all openssl like*/
2018 	if (headers) {
2019 		val = g_hash_table_lookup (headers, "Proc-Type");
2020 		if (val && strcmp (val, "4,ENCRYPTED") == 0)
2021 			encrypted = TRUE;
2022 	}
2023 
2024 	if (encrypted)
2025 		res = handle_encrypted_pem (args->parser, inner_format,
2026 		                            args->want_format, headers,
2027 		                            data);
2028 	else
2029 		res = handle_plain_pem (args->parser, inner_format,
2030 		                        args->want_format, data);
2031 
2032 	pop_parsed (args->parser, parsed);
2033 
2034 	if (res != GCR_ERROR_UNRECOGNIZED) {
2035 		if (args->result == GCR_ERROR_UNRECOGNIZED)
2036 			args->result = res;
2037 		else if (res > args->result)
2038 			args->result = res;
2039 	}
2040 }
2041 
2042 static gint
handle_pem_format(GcrParser * self,gint subformat,GBytes * data)2043 handle_pem_format (GcrParser *self,
2044                    gint subformat,
2045                    GBytes *data)
2046 {
2047 	HandlePemArgs ctx = { self, GCR_ERROR_UNRECOGNIZED, subformat };
2048 	guint found;
2049 
2050 	if (g_bytes_get_size (data) == 0)
2051 		return GCR_ERROR_UNRECOGNIZED;
2052 
2053 	found = egg_armor_parse (data, handle_pem_data, &ctx);
2054 
2055 	if (found == 0)
2056 		return GCR_ERROR_UNRECOGNIZED;
2057 
2058 	return ctx.result;
2059 }
2060 
2061 
2062 static gint
parse_pem(GcrParser * self,GBytes * data)2063 parse_pem (GcrParser *self,
2064            GBytes *data)
2065 {
2066 	return handle_pem_format (self, 0, data);
2067 }
2068 
2069 static gint
parse_pem_private_key_rsa(GcrParser * self,GBytes * data)2070 parse_pem_private_key_rsa (GcrParser *self,
2071                            GBytes *data)
2072 {
2073 	return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_RSA, data);
2074 }
2075 
2076 static gint
parse_pem_private_key_dsa(GcrParser * self,GBytes * data)2077 parse_pem_private_key_dsa (GcrParser *self,
2078                            GBytes *data)
2079 {
2080 	return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_DSA, data);
2081 }
2082 
2083 static gint
parse_pem_private_key_ec(GcrParser * self,GBytes * data)2084 parse_pem_private_key_ec (GcrParser *self,
2085 		          GBytes *data)
2086 {
2087 	return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_EC, data);
2088 }
2089 
2090 static gint
parse_pem_public_key(GcrParser * self,GBytes * data)2091 parse_pem_public_key (GcrParser *self,
2092                       GBytes *data)
2093 {
2094 	return handle_pem_format (self, GCR_FORMAT_DER_SUBJECT_PUBLIC_KEY, data);
2095 }
2096 
2097 static gint
parse_pem_certificate(GcrParser * self,GBytes * data)2098 parse_pem_certificate (GcrParser *self,
2099                        GBytes *data)
2100 {
2101 	return handle_pem_format (self, GCR_FORMAT_DER_CERTIFICATE_X509, data);
2102 }
2103 
2104 static gint
parse_pem_pkcs8_plain(GcrParser * self,GBytes * data)2105 parse_pem_pkcs8_plain (GcrParser *self,
2106                        GBytes *data)
2107 {
2108 	return handle_pem_format (self, GCR_FORMAT_DER_PKCS8_PLAIN, data);
2109 }
2110 
2111 static gint
parse_pem_pkcs8_encrypted(GcrParser * self,GBytes * data)2112 parse_pem_pkcs8_encrypted (GcrParser *self,
2113                            GBytes *data)
2114 {
2115 	return handle_pem_format (self, GCR_FORMAT_DER_PKCS8_ENCRYPTED, data);
2116 }
2117 
2118 static gint
parse_pem_pkcs7(GcrParser * self,GBytes * data)2119 parse_pem_pkcs7 (GcrParser *self,
2120                  GBytes *data)
2121 {
2122 	return handle_pem_format (self, GCR_FORMAT_DER_PKCS7, data);
2123 }
2124 
2125 static gint
parse_pem_pkcs10(GcrParser * self,GBytes * data)2126 parse_pem_pkcs10 (GcrParser *self,
2127                   GBytes *data)
2128 {
2129 	return handle_pem_format (self, GCR_FORMAT_DER_PKCS10, data);
2130 }
2131 
2132 static gint
parse_pem_pkcs12(GcrParser * self,GBytes * data)2133 parse_pem_pkcs12 (GcrParser *self,
2134                   GBytes *data)
2135 {
2136 	return handle_pem_format (self, GCR_FORMAT_DER_PKCS12, data);
2137 }
2138 
2139 static gint
parse_openpgp_armor(GcrParser * self,GBytes * data)2140 parse_openpgp_armor (GcrParser *self,
2141                      GBytes *data)
2142 {
2143 	return handle_pem_format (self, GCR_FORMAT_OPENPGP_PACKET, data);
2144 }
2145 
2146 /* -----------------------------------------------------------------------------
2147  * OPENSSH
2148  */
2149 
2150 static void
on_openssh_public_key_parsed(GckAttributes * attrs,const gchar * label,const gchar * options,GBytes * outer,gpointer user_data)2151 on_openssh_public_key_parsed (GckAttributes *attrs,
2152                               const gchar *label,
2153                               const gchar *options,
2154                               GBytes *outer,
2155                               gpointer user_data)
2156 {
2157 	GcrParser *self = GCR_PARSER (user_data);
2158 	GcrParsed *parsed;
2159 
2160 	parsed = push_parsed (self, FALSE);
2161 	parsing_block (parsed, GCR_FORMAT_OPENSSH_PUBLIC, outer);
2162 	parsed_attributes (parsed, attrs);
2163 	parsed_label (parsed, label);
2164 	parsed_fire (self, parsed);
2165 	pop_parsed (self, parsed);
2166 }
2167 
2168 static gint
parse_openssh_public(GcrParser * self,GBytes * data)2169 parse_openssh_public (GcrParser *self,
2170                       GBytes *data)
2171 {
2172 	guint num_parsed;
2173 
2174 	num_parsed = _gcr_openssh_pub_parse (data, on_openssh_public_key_parsed, self);
2175 
2176 	if (num_parsed == 0)
2177 		return GCR_ERROR_UNRECOGNIZED;
2178 	return SUCCESS;
2179 }
2180 
2181 /* -----------------------------------------------------------------------------
2182  * FORMATS
2183  */
2184 
2185 /**
2186  * GcrDataFormat:
2187  * @GCR_FORMAT_ALL: Represents all the formats, when enabling or disabling
2188  * @GCR_FORMAT_INVALID: Not a valid format
2189  * @GCR_FORMAT_DER_PRIVATE_KEY: DER encoded private key
2190  * @GCR_FORMAT_DER_PRIVATE_KEY_RSA: DER encoded RSA private key
2191  * @GCR_FORMAT_DER_PRIVATE_KEY_DSA: DER encoded DSA private key
2192  * @GCR_FORMAT_DER_PRIVATE_KEY_EC: DER encoded EC private key
2193  * @GCR_FORMAT_DER_SUBJECT_PUBLIC_KEY: DER encoded SubjectPublicKeyInfo
2194  * @GCR_FORMAT_DER_CERTIFICATE_X509: DER encoded X.509 certificate
2195  * @GCR_FORMAT_DER_PKCS7: DER encoded PKCS\#7 container file which can contain certificates
2196  * @GCR_FORMAT_DER_PKCS8: DER encoded PKCS\#8 file which can contain a key
2197  * @GCR_FORMAT_DER_PKCS8_PLAIN: Unencrypted DER encoded PKCS\#8 file which can contain a key
2198  * @GCR_FORMAT_DER_PKCS8_ENCRYPTED: Encrypted DER encoded PKCS\#8 file which can contain a key
2199  * @GCR_FORMAT_DER_PKCS10: DER encoded PKCS\#10 certificate request file
2200  * @GCR_FORMAT_DER_PKCS12: DER encoded PKCS\#12 file which can contain certificates and/or keys
2201  * @GCR_FORMAT_OPENSSH_PUBLIC: OpenSSH v1 or v2 public key
2202  * @GCR_FORMAT_OPENPGP_PACKET: OpenPGP key packet(s)
2203  * @GCR_FORMAT_OPENPGP_ARMOR: OpenPGP public or private key armor encoded data
2204  * @GCR_FORMAT_PEM: An OpenSSL style PEM file with unspecified contents
2205  * @GCR_FORMAT_PEM_PRIVATE_KEY: An OpenSSL style PEM file with a private key
2206  * @GCR_FORMAT_PEM_PRIVATE_KEY_RSA: An OpenSSL style PEM file with a private RSA key
2207  * @GCR_FORMAT_PEM_PRIVATE_KEY_DSA: An OpenSSL style PEM file with a private DSA key
2208  * @GCR_FORMAT_PEM_PRIVATE_KEY_EC: An OpenSSL style PEM file with a private EC key
2209  * @GCR_FORMAT_PEM_CERTIFICATE_X509: An OpenSSL style PEM file with an X.509 certificate
2210  * @GCR_FORMAT_PEM_PKCS7: An OpenSSL style PEM file containing PKCS\#7
2211  * @GCR_FORMAT_PEM_PKCS8_PLAIN: Unencrypted OpenSSL style PEM file containing PKCS\#8
2212  * @GCR_FORMAT_PEM_PKCS8_ENCRYPTED: Encrypted OpenSSL style PEM file containing PKCS\#8
2213  * @GCR_FORMAT_PEM_PKCS10: An OpenSSL style PEM file containing PKCS\#10
2214  * @GCR_FORMAT_PEM_PKCS12: An OpenSSL style PEM file containing PKCS\#12
2215  * @GCR_FORMAT_PEM_PUBLIC_KEY: An OpenSSL style PEM file containing a SubjectPublicKeyInfo
2216  * @GCR_FORMAT_DER_SPKAC: DER encoded SPKAC as generated by HTML5 keygen element
2217  * @GCR_FORMAT_BASE64_SPKAC: OpenSSL style SPKAC data
2218  *
2219  * The various format identifiers.
2220  */
2221 
2222 /*
2223  * In order of parsing when no formats specified. We put formats earlier
2224  * if the parser can quickly detect whether GCR_ERROR_UNRECOGNIZED or not
2225  */
2226 
2227 static const ParserFormat parser_normal[] = {
2228 	{ GCR_FORMAT_PEM, parse_pem },
2229 	{ GCR_FORMAT_BASE64_SPKAC, parse_base64_spkac },
2230 	{ GCR_FORMAT_DER_PRIVATE_KEY_RSA, parse_der_private_key_rsa },
2231 	{ GCR_FORMAT_DER_PRIVATE_KEY_DSA, parse_der_private_key_dsa },
2232 	{ GCR_FORMAT_DER_PRIVATE_KEY_EC, parse_der_private_key_ec },
2233 	{ GCR_FORMAT_DER_SUBJECT_PUBLIC_KEY, parse_der_subject_public_key },
2234 	{ GCR_FORMAT_DER_CERTIFICATE_X509, parse_der_certificate },
2235 	{ GCR_FORMAT_DER_PKCS7, parse_der_pkcs7 },
2236 	{ GCR_FORMAT_DER_PKCS8_PLAIN, parse_der_pkcs8_plain },
2237 	{ GCR_FORMAT_DER_PKCS8_ENCRYPTED, parse_der_pkcs8_encrypted },
2238 	{ GCR_FORMAT_DER_PKCS12, parse_der_pkcs12 },
2239 	{ GCR_FORMAT_OPENSSH_PUBLIC, parse_openssh_public },
2240 	{ GCR_FORMAT_OPENPGP_PACKET, parse_openpgp_packets },
2241 	{ GCR_FORMAT_OPENPGP_ARMOR, parse_openpgp_armor },
2242 	{ GCR_FORMAT_DER_PKCS10, parse_der_pkcs10 },
2243 	{ GCR_FORMAT_DER_SPKAC, parse_der_spkac },
2244 };
2245 
2246 /* Must be in format_id numeric order */
2247 static const ParserFormat parser_formats[] = {
2248 	{ GCR_FORMAT_DER_PRIVATE_KEY, parse_der_private_key },
2249 	{ GCR_FORMAT_DER_PRIVATE_KEY_RSA, parse_der_private_key_rsa },
2250 	{ GCR_FORMAT_DER_PRIVATE_KEY_DSA, parse_der_private_key_dsa },
2251 	{ GCR_FORMAT_DER_PRIVATE_KEY_EC, parse_der_private_key_ec },
2252 	{ GCR_FORMAT_DER_SUBJECT_PUBLIC_KEY, parse_der_subject_public_key },
2253 	{ GCR_FORMAT_DER_CERTIFICATE_X509, parse_der_certificate },
2254 	{ GCR_FORMAT_DER_PKCS7, parse_der_pkcs7 },
2255 	{ GCR_FORMAT_DER_PKCS8, parse_der_pkcs8 },
2256 	{ GCR_FORMAT_DER_PKCS8_PLAIN, parse_der_pkcs8_plain },
2257 	{ GCR_FORMAT_DER_PKCS8_ENCRYPTED, parse_der_pkcs8_encrypted },
2258 	{ GCR_FORMAT_DER_PKCS10, parse_der_pkcs10 },
2259 	{ GCR_FORMAT_DER_SPKAC, parse_der_spkac },
2260 	{ GCR_FORMAT_BASE64_SPKAC, parse_base64_spkac },
2261 	{ GCR_FORMAT_DER_PKCS12, parse_der_pkcs12 },
2262 	{ GCR_FORMAT_OPENSSH_PUBLIC, parse_openssh_public },
2263 	{ GCR_FORMAT_OPENPGP_PACKET, parse_openpgp_packets },
2264 	{ GCR_FORMAT_OPENPGP_ARMOR, parse_openpgp_armor },
2265 	{ GCR_FORMAT_PEM, parse_pem },
2266 	{ GCR_FORMAT_PEM_PRIVATE_KEY_RSA, parse_pem_private_key_rsa },
2267 	{ GCR_FORMAT_PEM_PRIVATE_KEY_DSA, parse_pem_private_key_dsa },
2268 	{ GCR_FORMAT_PEM_CERTIFICATE_X509, parse_pem_certificate },
2269 	{ GCR_FORMAT_PEM_PKCS7, parse_pem_pkcs7 },
2270 	{ GCR_FORMAT_PEM_PKCS8_PLAIN, parse_pem_pkcs8_plain },
2271 	{ GCR_FORMAT_PEM_PKCS8_ENCRYPTED, parse_pem_pkcs8_encrypted },
2272 	{ GCR_FORMAT_PEM_PKCS12, parse_pem_pkcs12 },
2273 	{ GCR_FORMAT_PEM_PKCS10, parse_pem_pkcs10 },
2274 	{ GCR_FORMAT_PEM_PRIVATE_KEY_EC, parse_pem_private_key_ec },
2275 	{ GCR_FORMAT_PEM_PUBLIC_KEY, parse_pem_public_key },
2276 };
2277 
2278 static int
compar_id_to_parser_format(const void * a,const void * b)2279 compar_id_to_parser_format (const void *a, const void *b)
2280 {
2281 	const gint *format_id = a;
2282 	const ParserFormat *format = b;
2283 
2284 	g_assert (format_id);
2285 	g_assert (format);
2286 
2287 	if (format->format_id == *format_id)
2288 		return 0;
2289 	return (*format_id < format->format_id) ? -1 : 1;
2290 }
2291 
2292 static ParserFormat*
parser_format_lookup(gint format_id)2293 parser_format_lookup (gint format_id)
2294 {
2295 	return bsearch (&format_id, parser_formats, G_N_ELEMENTS (parser_formats),
2296 	                sizeof (parser_formats[0]), compar_id_to_parser_format);
2297 }
2298 
2299 static gint
compare_pointers(gconstpointer a,gconstpointer b)2300 compare_pointers (gconstpointer a, gconstpointer b)
2301 {
2302 	if (a == b)
2303 		return 0;
2304 	return a < b ? -1 : 1;
2305 }
2306 
2307 typedef struct _ForeachArgs {
2308 	GcrParser *parser;
2309 	GBytes *data;
2310 	gint result;
2311 } ForeachArgs;
2312 
2313 static gboolean
parser_format_foreach(gpointer key,gpointer value,gpointer data)2314 parser_format_foreach (gpointer key, gpointer value, gpointer data)
2315 {
2316 	ForeachArgs *args = data;
2317 	ParserFormat *format = key;
2318 	gint result;
2319 
2320 	g_assert (format);
2321 	g_assert (format->function);
2322 	g_assert (GCR_IS_PARSER (args->parser));
2323 
2324 	result = (format->function) (args->parser, args->data);
2325 	if (result != GCR_ERROR_UNRECOGNIZED) {
2326 		args->result = result;
2327 		return TRUE;
2328 	}
2329 
2330 	/* Keep going */
2331 	return FALSE;
2332 }
2333 
2334 /* -----------------------------------------------------------------------------
2335  * OBJECT
2336  */
2337 
2338 
2339 static GObject*
gcr_parser_constructor(GType type,guint n_props,GObjectConstructParam * props)2340 gcr_parser_constructor (GType type, guint n_props, GObjectConstructParam *props)
2341 {
2342 	GcrParser *self = GCR_PARSER (G_OBJECT_CLASS (gcr_parser_parent_class)->constructor(type, n_props, props));
2343 	g_return_val_if_fail (self, NULL);
2344 
2345 	/* Always try to parse with NULL and empty passwords first */
2346 	gcr_parser_add_password (self, NULL);
2347 	gcr_parser_add_password (self, "");
2348 
2349 	return G_OBJECT (self);
2350 }
2351 
2352 static void
gcr_parser_init(GcrParser * self)2353 gcr_parser_init (GcrParser *self)
2354 {
2355 	self->pv = gcr_parser_get_instance_private (self);
2356 	self->pv->passwords = g_ptr_array_new ();
2357 	self->pv->normal_formats = TRUE;
2358 }
2359 
2360 static void
gcr_parser_dispose(GObject * obj)2361 gcr_parser_dispose (GObject *obj)
2362 {
2363 	GcrParser *self = GCR_PARSER (obj);
2364 	gsize i;
2365 
2366 	g_assert (!self->pv->parsed);
2367 
2368 	if (self->pv->specific_formats)
2369 		g_tree_destroy (self->pv->specific_formats);
2370 	self->pv->specific_formats = NULL;
2371 
2372 	for (i = 0; i < self->pv->passwords->len; ++i)
2373 		egg_secure_strfree (g_ptr_array_index (self->pv->passwords, i));
2374 	g_ptr_array_set_size (self->pv->passwords, 0);
2375 
2376 	G_OBJECT_CLASS (gcr_parser_parent_class)->dispose (obj);
2377 }
2378 
2379 static void
gcr_parser_finalize(GObject * obj)2380 gcr_parser_finalize (GObject *obj)
2381 {
2382 	GcrParser *self = GCR_PARSER (obj);
2383 
2384 	g_assert (!self->pv->parsed);
2385 
2386 	g_ptr_array_free (self->pv->passwords, TRUE);
2387 	self->pv->passwords = NULL;
2388 
2389 	g_free (self->pv->filename);
2390 	self->pv->filename = NULL;
2391 
2392 	G_OBJECT_CLASS (gcr_parser_parent_class)->finalize (obj);
2393 }
2394 
2395 static void
gcr_parser_set_property(GObject * obj,guint prop_id,const GValue * value,GParamSpec * pspec)2396 gcr_parser_set_property (GObject *obj, guint prop_id, const GValue *value,
2397                            GParamSpec *pspec)
2398 {
2399 	switch (prop_id) {
2400 	default:
2401 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
2402 		break;
2403 	}
2404 }
2405 
2406 static void
gcr_parser_get_property(GObject * obj,guint prop_id,GValue * value,GParamSpec * pspec)2407 gcr_parser_get_property (GObject *obj, guint prop_id, GValue *value,
2408                          GParamSpec *pspec)
2409 {
2410 	GcrParser *self = GCR_PARSER (obj);
2411 
2412 	switch (prop_id) {
2413 	case PROP_PARSED_ATTRIBUTES:
2414 		g_value_set_boxed (value, gcr_parser_get_parsed_attributes (self));
2415 		break;
2416 	case PROP_PARSED_LABEL:
2417 		g_value_set_string (value, gcr_parser_get_parsed_label (self));
2418 		break;
2419 	case PROP_PARSED_DESCRIPTION:
2420 		g_value_set_string (value, gcr_parser_get_parsed_description (self));
2421 		break;
2422 	default:
2423 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
2424 		break;
2425 	}
2426 }
2427 
2428 static void
gcr_parser_class_init(GcrParserClass * klass)2429 gcr_parser_class_init (GcrParserClass *klass)
2430 {
2431 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
2432 	gint i;
2433 
2434 	gobject_class->constructor = gcr_parser_constructor;
2435 	gobject_class->dispose = gcr_parser_dispose;
2436 	gobject_class->finalize = gcr_parser_finalize;
2437 	gobject_class->set_property = gcr_parser_set_property;
2438 	gobject_class->get_property = gcr_parser_get_property;
2439 
2440 	/**
2441 	 * GcrParser:parsed-attributes:
2442 	 *
2443 	 * Get the attributes that make up the currently parsed item. This is
2444 	 * generally only valid during a #GcrParser::parsed signal.
2445 	 */
2446 	g_object_class_install_property (gobject_class, PROP_PARSED_ATTRIBUTES,
2447 	           g_param_spec_boxed ("parsed-attributes", "Parsed Attributes", "Parsed PKCS#11 attributes",
2448 	                               GCK_TYPE_ATTRIBUTES,
2449 	                               G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
2450 
2451 	/**
2452 	 * GcrParser:parsed-label:
2453 	 *
2454 	 * The label of the currently parsed item. This is generally
2455 	 * only valid during a #GcrParser::parsed signal.
2456 	 */
2457 	g_object_class_install_property (gobject_class, PROP_PARSED_LABEL,
2458 	           g_param_spec_string ("parsed-label", "Parsed Label", "Parsed item label",
2459 	                                "",
2460 	                                G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
2461 
2462 	/**
2463 	 * GcrParser:parsed-description:
2464 	 *
2465 	 * The description of the type of the currently parsed item. This is generally
2466 	 * only valid during a #GcrParser::parsed signal.
2467 	 */
2468 	g_object_class_install_property (gobject_class, PROP_PARSED_DESCRIPTION,
2469 	           g_param_spec_string ("parsed-description", "Parsed Description", "Parsed item description",
2470 	                                "",
2471 	                                G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
2472 
2473 	/**
2474 	 * GcrParser::authenticate:
2475 	 * @self: the parser
2476 	 * @count: the number of times this item has been authenticated
2477 	 *
2478 	 * This signal is emitted when an item needs to be unlocked or decrypted before
2479 	 * it can be parsed. The @count argument specifies the number of times
2480 	 * the signal has been emitted for a given item. This can be used to
2481 	 * display a message saying the previous password was incorrect.
2482 	 *
2483 	 * Typically the gcr_parser_add_password() function is called in
2484 	 * response to this signal.
2485 	 *
2486 	 * If %FALSE is returned, then the authentication was not handled. If
2487 	 * no handlers return %TRUE then the item is not parsed and an error
2488 	 * with the code %GCR_ERROR_CANCELLED will be raised.
2489 	 *
2490 	 * Returns: Whether the authentication was handled.
2491 	 */
2492 	signals[AUTHENTICATE] = g_signal_new ("authenticate", GCR_TYPE_PARSER,
2493 	                                G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GcrParserClass, authenticate),
2494 	                                g_signal_accumulator_true_handled, NULL, _gcr_marshal_BOOLEAN__INT,
2495 	                                G_TYPE_BOOLEAN, 1, G_TYPE_INT);
2496 
2497 	/**
2498 	 * GcrParser::parsed:
2499 	 * @self: the parser
2500 	 *
2501 	 * This signal is emitted when an item is sucessfully parsed. To access
2502 	 * the information about the item use the gcr_parser_get_parsed_label(),
2503 	 * gcr_parser_get_parsed_attributes() and gcr_parser_get_parsed_description()
2504 	 * functions.
2505 	 */
2506 	signals[PARSED] = g_signal_new ("parsed", GCR_TYPE_PARSER,
2507 	                                G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GcrParserClass, parsed),
2508 	                                NULL, NULL, NULL,
2509 	                                G_TYPE_NONE, 0);
2510 
2511 	init_quarks ();
2512 	_gcr_initialize_library ();
2513 
2514 	/* Check that the format tables are in order */
2515 	for (i = 1; i < G_N_ELEMENTS (parser_formats); ++i)
2516 		g_assert (parser_formats[i].format_id >= parser_formats[i - 1].format_id);
2517 }
2518 
2519 /* -----------------------------------------------------------------------------
2520  * PUBLIC
2521  */
2522 
2523 /**
2524  * gcr_parser_new:
2525  *
2526  * Create a new #GcrParser
2527  *
2528  * Returns: (transfer full): a newly allocated #GcrParser
2529  */
2530 GcrParser *
gcr_parser_new(void)2531 gcr_parser_new (void)
2532 {
2533 	return g_object_new (GCR_TYPE_PARSER, NULL);
2534 }
2535 
2536 /**
2537  * gcr_parser_add_password:
2538  * @self: The parser
2539  * @password: (nullable): a password to try
2540  *
2541  * Add a password to the set of passwords to try when parsing locked or encrypted
2542  * items. This is usually called from the #GcrParser::authenticate signal.
2543  */
2544 void
gcr_parser_add_password(GcrParser * self,const gchar * password)2545 gcr_parser_add_password (GcrParser *self, const gchar *password)
2546 {
2547 	g_return_if_fail (GCR_IS_PARSER (self));
2548 	g_ptr_array_add (self->pv->passwords, egg_secure_strdup (password));
2549 }
2550 
2551 /**
2552  * gcr_parser_parse_bytes:
2553  * @self: The parser
2554  * @data: the data to parse
2555  * @error: A location to raise an error on failure.
2556  *
2557  * Parse the data. The #GcrParser::parsed and #GcrParser::authenticate signals
2558  * may fire during the parsing.
2559  *
2560  * Returns: Whether the data was parsed successfully or not.
2561  */
2562 gboolean
gcr_parser_parse_bytes(GcrParser * self,GBytes * data,GError ** error)2563 gcr_parser_parse_bytes (GcrParser *self,
2564                         GBytes *data,
2565                         GError **error)
2566 {
2567 	ForeachArgs args = { self, NULL, GCR_ERROR_UNRECOGNIZED };
2568 	const gchar *message = NULL;
2569 	gint i;
2570 
2571 	g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
2572 	g_return_val_if_fail (data != NULL, FALSE);
2573 	g_return_val_if_fail (!error || !*error, FALSE);
2574 
2575 	if (g_bytes_get_size (data) > 0) {
2576 		args.data = g_bytes_ref (data);
2577 
2578 		/* Just the specific formats requested */
2579 		if (self->pv->specific_formats) {
2580 			g_tree_foreach (self->pv->specific_formats, parser_format_foreach, &args);
2581 
2582 		/* All the 'normal' formats */
2583 		} else if (self->pv->normal_formats) {
2584 			for (i = 0; i < G_N_ELEMENTS (parser_normal); ++i) {
2585 				if (parser_format_foreach ((gpointer)(parser_normal + i),
2586 							   (gpointer)(parser_normal + i), &args))
2587 					break;
2588 			}
2589 		}
2590 
2591 		g_bytes_unref (args.data);
2592 	}
2593 
2594 	switch (args.result) {
2595 	case SUCCESS:
2596 		return TRUE;
2597 	case GCR_ERROR_CANCELLED:
2598 		message = _("The operation was cancelled");
2599 		break;
2600 	case GCR_ERROR_UNRECOGNIZED:
2601 		message = _("Unrecognized or unsupported data.");
2602 		break;
2603 	case GCR_ERROR_FAILURE:
2604 		message = _("Could not parse invalid or corrupted data.");
2605 		break;
2606 	case GCR_ERROR_LOCKED:
2607 		message = _("The data is locked");
2608 		break;
2609 	default:
2610 		g_assert_not_reached ();
2611 		break;
2612 	};
2613 
2614 	g_set_error_literal (error, GCR_DATA_ERROR, args.result, message);
2615 	return FALSE;
2616 }
2617 
2618 /**
2619  * gcr_parser_parse_data:
2620  * @self: The parser
2621  * @data: (array length=n_data): the data to parse
2622  * @n_data: The length of the data
2623  * @error: A location to raise an error on failure.
2624  *
2625  * Parse the data. The #GcrParser::parsed and #GcrParser::authenticate signals
2626  * may fire during the parsing.
2627  *
2628  * A copy of the data will be made. Use gcr_parser_parse_bytes() to avoid this.
2629  *
2630  * Returns: Whether the data was parsed successfully or not.
2631  */
2632 gboolean
gcr_parser_parse_data(GcrParser * self,const guchar * data,gsize n_data,GError ** error)2633 gcr_parser_parse_data (GcrParser *self,
2634                        const guchar *data,
2635                        gsize n_data,
2636                        GError **error)
2637 {
2638 	GBytes *bytes;
2639 	gboolean ret;
2640 
2641 	g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
2642 	g_return_val_if_fail (data || !n_data, FALSE);
2643 	g_return_val_if_fail (!error || !*error, FALSE);
2644 
2645 	bytes = g_bytes_new (data, n_data);
2646 	ret = gcr_parser_parse_bytes (self, bytes, error);
2647 	g_bytes_unref (bytes);
2648 
2649 	return ret;
2650 }
2651 
2652 /**
2653  * gcr_parser_format_enable:
2654  * @self: The parser
2655  * @format: The format identifier
2656  *
2657  * Enable parsing of the given format. Use %GCR_FORMAT_ALL to enable all the formats.
2658  */
2659 void
gcr_parser_format_enable(GcrParser * self,GcrDataFormat format)2660 gcr_parser_format_enable (GcrParser *self,
2661                           GcrDataFormat format)
2662 {
2663 	const ParserFormat *form;
2664 	guint i;
2665 
2666 	g_return_if_fail (GCR_IS_PARSER (self));
2667 
2668 	if (!self->pv->specific_formats)
2669 		self->pv->specific_formats = g_tree_new (compare_pointers);
2670 
2671 	if (format != -1) {
2672 		form = parser_format_lookup (format);
2673 		g_return_if_fail (form);
2674 		g_tree_insert (self->pv->specific_formats,
2675 		               (gpointer)form, (gpointer)form);
2676 	} else {
2677 		for (i = 0; i < G_N_ELEMENTS (parser_formats); i++) {
2678 			form = &parser_formats[i];
2679 			g_tree_insert (self->pv->specific_formats, (gpointer)form,
2680 			               (gpointer)form);
2681 		}
2682 	}
2683 }
2684 
2685 /**
2686  * gcr_parser_format_disable:
2687  * @self: The parser
2688  * @format: The format identifier
2689  *
2690  * Disable parsing of the given format. Use %GCR_FORMAT_ALL to disable all the formats.
2691  */
2692 void
gcr_parser_format_disable(GcrParser * self,GcrDataFormat format)2693 gcr_parser_format_disable (GcrParser *self,
2694                            GcrDataFormat format)
2695 {
2696 	ParserFormat *form;
2697 
2698 	g_return_if_fail (GCR_IS_PARSER (self));
2699 
2700 	if (format == -1) {
2701 		if (self->pv->specific_formats)
2702 			g_tree_destroy (self->pv->specific_formats);
2703 		self->pv->specific_formats = NULL;
2704 		self->pv->normal_formats = FALSE;
2705 	}
2706 
2707 	if (!self->pv->specific_formats)
2708 		return;
2709 
2710 	form = parser_format_lookup (format);
2711 	g_return_if_fail (form);
2712 
2713 	g_tree_remove (self->pv->specific_formats, form);
2714 }
2715 
2716 /**
2717  * gcr_parser_format_supported:
2718  * @self: The parser
2719  * @format: The format identifier
2720  *
2721  * Check whether the given format is supported by the parser.
2722  *
2723  * Returns: Whether the format is supported.
2724  */
2725 gboolean
gcr_parser_format_supported(GcrParser * self,GcrDataFormat format)2726 gcr_parser_format_supported (GcrParser *self,
2727                              GcrDataFormat format)
2728 {
2729 	g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
2730 	g_return_val_if_fail (format != GCR_FORMAT_ALL, FALSE);
2731 	g_return_val_if_fail (format != GCR_FORMAT_INVALID, FALSE);
2732 	return parser_format_lookup (format) ? TRUE : FALSE;
2733 }
2734 
2735 /**
2736  * gcr_parser_get_parsed:
2737  * @self: a parser
2738  *
2739  * Get the currently parsed item
2740  *
2741  * Returns: (transfer none): the currently parsed item
2742  */
2743 GcrParsed *
gcr_parser_get_parsed(GcrParser * self)2744 gcr_parser_get_parsed (GcrParser *self)
2745 {
2746 	g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
2747 	return self->pv->parsed;
2748 }
2749 
G_DEFINE_BOXED_TYPE(GcrParsed,gcr_parsed,gcr_parsed_ref,gcr_parsed_unref)2750 G_DEFINE_BOXED_TYPE (GcrParsed, gcr_parsed, gcr_parsed_ref, gcr_parsed_unref)
2751 
2752 /**
2753  * gcr_parser_get_filename:
2754  * @self: a parser item
2755  *
2756  * Get the filename of the parser item.
2757  *
2758  * Returns: the filename set on the parser, or %NULL
2759  */
2760 const gchar *
2761 gcr_parser_get_filename (GcrParser *self)
2762 {
2763 	g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
2764 	return self->pv->filename;
2765 }
2766 
2767 /**
2768  * gcr_parser_set_filename:
2769  * @self: a parser item
2770  * @filename: (nullable): a string of the filename of the parser item
2771  *
2772  * Sets the filename of the parser item.
2773  */
2774 void
gcr_parser_set_filename(GcrParser * self,const gchar * filename)2775 gcr_parser_set_filename (GcrParser *self,
2776                          const gchar *filename)
2777 {
2778 	g_return_if_fail (GCR_IS_PARSER (self));
2779 	g_free (self->pv->filename);
2780 	self->pv->filename = g_strdup (filename);
2781 }
2782 
2783 /**
2784  * gcr_parsed_ref:
2785  * @parsed: a parsed item
2786  *
2787  * Add a reference to a parsed item. An item may not be shared across threads
2788  * until it has been referenced at least once.
2789  *
2790  * Returns: (transfer full): the parsed item
2791  */
2792 GcrParsed *
gcr_parsed_ref(GcrParsed * parsed)2793 gcr_parsed_ref (GcrParsed *parsed)
2794 {
2795 	GcrParsed *copy;
2796 
2797 	g_return_val_if_fail (parsed != NULL, NULL);
2798 
2799 	/* Already had a reference */
2800 	if (g_atomic_int_add (&parsed->refs, 1) >= 1)
2801 		return parsed;
2802 
2803 	/* If this is the first reference, flatten the stack of parsed */
2804 	copy = g_new0 (GcrParsed, 1);
2805 	copy->refs = 1;
2806 	copy->label = g_strdup (gcr_parsed_get_label (parsed));
2807 	copy->filename = g_strdup (gcr_parsed_get_filename (parsed));
2808 	copy->attrs = gcr_parsed_get_attributes (parsed);
2809 	copy->format = gcr_parsed_get_format (parsed);
2810 	if (copy->attrs)
2811 		gck_attributes_ref (copy->attrs);
2812 	copy->description = gcr_parsed_get_description (parsed);
2813 	copy->next = NULL;
2814 
2815 	/* Find the block of data to copy */
2816 	while (parsed != NULL) {
2817 		if (parsed->data != NULL) {
2818 			copy->data = g_bytes_ref (parsed->data);
2819 			copy->sensitive = parsed->sensitive;
2820 			break;
2821 		}
2822 		parsed = parsed->next;
2823 	}
2824 
2825 	return copy;
2826 }
2827 
2828 /**
2829  * gcr_parsed_unref:
2830  * @parsed: a parsed item
2831  *
2832  * Unreferences a parsed item which was referenced with gcr_parsed_ref()
2833  */
2834 void
gcr_parsed_unref(gpointer parsed)2835 gcr_parsed_unref (gpointer parsed)
2836 {
2837 	GcrParsed *par = parsed;
2838 
2839 	g_return_if_fail (parsed != NULL);
2840 
2841 	if (g_atomic_int_dec_and_test (&par->refs)) {
2842 		_gcr_parsed_free (parsed);
2843 	}
2844 }
2845 
2846 /**
2847  * gcr_parser_get_parsed_description:
2848  * @self: The parser
2849  *
2850  * Get a description for the type of the currently parsed item. This is generally
2851  * only valid during the #GcrParser::parsed signal.
2852  *
2853  * Returns: (nullable): the description for the current item; this is owned by
2854  *          the parser and should not be freed
2855  */
2856 const gchar*
gcr_parser_get_parsed_description(GcrParser * self)2857 gcr_parser_get_parsed_description (GcrParser *self)
2858 {
2859 	g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
2860 	g_return_val_if_fail (self->pv->parsed != NULL, NULL);
2861 
2862 	return gcr_parsed_get_description (self->pv->parsed);
2863 }
2864 
2865 /**
2866  * gcr_parsed_get_description:
2867  * @parsed: a parsed item
2868  *
2869  * Get the descirption for a parsed item.
2870  *
2871  * Returns: (nullable): the description
2872  */
2873 const gchar*
gcr_parsed_get_description(GcrParsed * parsed)2874 gcr_parsed_get_description (GcrParsed *parsed)
2875 {
2876 	while (parsed != NULL) {
2877 		if (parsed->description != NULL)
2878 			return parsed->description;
2879 		parsed = parsed->next;
2880 	}
2881 
2882 	return NULL;
2883 }
2884 
2885 /**
2886  * gcr_parser_get_parsed_attributes:
2887  * @self: The parser
2888  *
2889  * Get the attributes which make up the currently parsed item. This is generally
2890  * only valid during the #GcrParser::parsed signal.
2891  *
2892  * Returns: (transfer none) (nullable): the attributes for the current item,
2893  *          which are owned by the parser and should not be freed
2894  */
2895 GckAttributes *
gcr_parser_get_parsed_attributes(GcrParser * self)2896 gcr_parser_get_parsed_attributes (GcrParser *self)
2897 {
2898 	g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
2899 	g_return_val_if_fail (self->pv->parsed != NULL, NULL);
2900 
2901 	return gcr_parsed_get_attributes (self->pv->parsed);
2902 }
2903 
2904 /**
2905  * gcr_parsed_get_attributes:
2906  * @parsed: a parsed item
2907  *
2908  * Get the attributes which make up the parsed item.
2909  *
2910  * Returns: (transfer none) (nullable): the attributes for the item; these
2911  *          are owned by the parsed item and should not be freed
2912  */
2913 GckAttributes *
gcr_parsed_get_attributes(GcrParsed * parsed)2914 gcr_parsed_get_attributes (GcrParsed *parsed)
2915 {
2916 	while (parsed != NULL) {
2917 		if (parsed->attrs != NULL)
2918 			return parsed->attrs;
2919 		parsed = parsed->next;
2920 	}
2921 
2922 	return NULL;
2923 }
2924 
2925 /**
2926  * gcr_parser_get_parsed_label:
2927  * @self: The parser
2928  *
2929  * Get the label of the currently parsed item. This is generally only valid
2930  * during the #GcrParser::parsed signal.
2931  *
2932  * Returns: (nullable): the label of the currently parsed item. The value is
2933  *          owned by the parser and should not be freed.
2934  */
2935 const gchar*
gcr_parser_get_parsed_label(GcrParser * self)2936 gcr_parser_get_parsed_label (GcrParser *self)
2937 {
2938 	g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
2939 	g_return_val_if_fail (self->pv->parsed != NULL, NULL);
2940 
2941 	return gcr_parsed_get_label (self->pv->parsed);
2942 }
2943 
2944 /**
2945  * gcr_parsed_get_label:
2946  * @parsed: a parsed item
2947  *
2948  * Get the label for the parsed item.
2949  *
2950  * Returns: (nullable): the label for the item
2951  */
2952 const gchar*
gcr_parsed_get_label(GcrParsed * parsed)2953 gcr_parsed_get_label (GcrParsed *parsed)
2954 {
2955 	while (parsed != NULL) {
2956 		if (parsed->label != NULL)
2957 			return parsed->label;
2958 		parsed = parsed->next;
2959 	}
2960 
2961 	return NULL;
2962 }
2963 
2964 /**
2965  * gcr_parser_get_parsed_block:
2966  * @self: a parser
2967  * @n_block: a location to place the size of the block
2968  *
2969  * Get the raw data block that represents this parsed object. This is only
2970  * valid during the #GcrParser::parsed signal.
2971  *
2972  * Returns: (transfer none) (array length=n_block) (nullable): the raw data
2973  *          block of the currently parsed item; the value is owned by the parser
2974  *          and should not be freed
2975  */
2976 const guchar *
gcr_parser_get_parsed_block(GcrParser * self,gsize * n_block)2977 gcr_parser_get_parsed_block (GcrParser *self,
2978                              gsize *n_block)
2979 {
2980 	g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
2981 	g_return_val_if_fail (n_block != NULL, NULL);
2982 	g_return_val_if_fail (self->pv->parsed != NULL, NULL);
2983 
2984 	return gcr_parsed_get_data (self->pv->parsed, n_block);
2985 }
2986 
2987 
2988 /**
2989  * gcr_parser_get_parsed_bytes:
2990  * @self: a parser
2991  *
2992  * Get the raw data block that represents this parsed object. This is only
2993  * valid during the #GcrParser::parsed signal.
2994  *
2995  * Returns: (transfer none): the raw data block of the currently parsed item
2996  */
2997 GBytes *
gcr_parser_get_parsed_bytes(GcrParser * self)2998 gcr_parser_get_parsed_bytes (GcrParser *self)
2999 {
3000 	return gcr_parsed_get_bytes (self->pv->parsed);
3001 }
3002 
3003 /**
3004  * gcr_parsed_get_data:
3005  * @parsed: a parsed item
3006  * @n_data: location to store size of returned data
3007  *
3008  * Get the raw data block for the parsed item.
3009  *
3010  * Returns: (transfer none) (array length=n_data) (nullable): the raw data of
3011  *          the parsed item, or %NULL
3012  */
3013 const guchar *
gcr_parsed_get_data(GcrParsed * parsed,gsize * n_data)3014 gcr_parsed_get_data (GcrParsed *parsed,
3015                      gsize *n_data)
3016 {
3017 	GBytes *bytes;
3018 
3019 	g_return_val_if_fail (n_data != NULL, NULL);
3020 
3021 	bytes = gcr_parsed_get_bytes (parsed);
3022 	if (bytes == NULL) {
3023 		*n_data = 0;
3024 		return NULL;
3025 	}
3026 
3027 	return g_bytes_get_data (bytes, n_data);
3028 }
3029 
3030 /**
3031  * gcr_parsed_get_bytes:
3032  * @parsed: a parsed item
3033  *
3034  * Get the raw data block for the parsed item.
3035  *
3036  * Returns: (transfer none): the raw data of the parsed item, or %NULL
3037  */
3038 GBytes *
gcr_parsed_get_bytes(GcrParsed * parsed)3039 gcr_parsed_get_bytes (GcrParsed *parsed)
3040 {
3041 	while (parsed != NULL) {
3042 		if (parsed->data != NULL)
3043 			return parsed->data;
3044 		parsed = parsed->next;
3045 	}
3046 
3047 	return NULL;
3048 }
3049 
3050 /**
3051  * gcr_parser_get_parsed_format:
3052  * @self: a parser
3053  *
3054  * Get the format of the raw data block that represents this parsed object.
3055  * This corresponds with the data returned from gcr_parser_get_parsed_block().
3056  *
3057  * This is only valid during the #GcrParser::parsed signal.
3058  *
3059  * Returns: the data format of the currently parsed item
3060  */
3061 GcrDataFormat
gcr_parser_get_parsed_format(GcrParser * self)3062 gcr_parser_get_parsed_format (GcrParser *self)
3063 {
3064 	g_return_val_if_fail (GCR_IS_PARSER (self), 0);
3065 	g_return_val_if_fail (self->pv->parsed != NULL, 0);
3066 
3067 	return gcr_parsed_get_format (self->pv->parsed);
3068 }
3069 
3070 /**
3071  * gcr_parsed_get_format:
3072  * @parsed: a parsed item
3073  *
3074  * Get the format of the parsed item.
3075  *
3076  * Returns: the data format of the item
3077  */
3078 GcrDataFormat
gcr_parsed_get_format(GcrParsed * parsed)3079 gcr_parsed_get_format (GcrParsed *parsed)
3080 {
3081 	while (parsed != NULL) {
3082 		if (parsed->data != NULL)
3083 			return parsed->format;
3084 		parsed = parsed->next;
3085 	}
3086 
3087 	return 0;
3088 }
3089 
3090 /**
3091  * gcr_parsed_get_filename:
3092  * @parsed: a parsed item
3093  *
3094  * Get the filename of the parsed item.
3095  *
3096  * Returns: (transfer none): the filename of
3097  *          the parsed item, or %NULL
3098  */
3099 const gchar *
gcr_parsed_get_filename(GcrParsed * parsed)3100 gcr_parsed_get_filename (GcrParsed *parsed)
3101 {
3102 	g_return_val_if_fail (parsed != NULL, NULL);
3103 	return parsed->filename;
3104 }
3105 /* ---------------------------------------------------------------------------------
3106  * STREAM PARSING
3107  */
3108 
3109 #define GCR_TYPE_PARSING        (gcr_parsing_get_type ())
3110 #define GCR_PARSING(obj)        (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_PARSING, GcrParsing))
3111 #define GCR_IS_PARSING(obj)     (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_PARSING))
3112 
3113 typedef struct _GcrParsing {
3114 	GObjectClass parent;
3115 
3116 	GcrParser *parser;
3117 	gboolean async;
3118 	GCancellable *cancel;
3119 
3120 	/* Failure information */
3121 	GError *error;
3122 	gboolean complete;
3123 
3124 	/* Operation state */
3125 	GInputStream *input;
3126 	GByteArray *buffer;
3127 
3128 	/* Async callback stuff */
3129 	GAsyncReadyCallback callback;
3130 	gpointer user_data;
3131 
3132 } GcrParsing;
3133 
3134 typedef struct _GcrParsingClass {
3135 	GObjectClass parent_class;
3136 } GcrParsingClass;
3137 
3138 /* State forward declarations */
3139 static void state_cancelled (GcrParsing *self, gboolean async);
3140 static void state_failure (GcrParsing *self, gboolean async);
3141 static void state_complete (GcrParsing *self, gboolean async);
3142 static void state_parse_buffer (GcrParsing *self, gboolean async);
3143 static void state_read_buffer (GcrParsing *self, gboolean async);
3144 
3145 /* Other forward declarations */
3146 static GType gcr_parsing_get_type (void) G_GNUC_CONST;
3147 static void gcr_parsing_async_result_init (GAsyncResultIface *iface);
3148 
3149 G_DEFINE_TYPE_WITH_CODE (GcrParsing, gcr_parsing, G_TYPE_OBJECT,
3150                          G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, gcr_parsing_async_result_init));
3151 
3152 #define BLOCK 4096
3153 
3154 static void
next_state(GcrParsing * self,void (* state)(GcrParsing *,gboolean))3155 next_state (GcrParsing *self, void (*state) (GcrParsing*, gboolean))
3156 {
3157 	g_assert (GCR_IS_PARSING (self));
3158 	g_assert (state);
3159 
3160 	if (self->cancel && g_cancellable_is_cancelled (self->cancel))
3161 		state = state_cancelled;
3162 
3163 	(state) (self, self->async);
3164 }
3165 
3166 static void
state_complete(GcrParsing * self,gboolean async)3167 state_complete (GcrParsing *self, gboolean async)
3168 {
3169 	g_assert (GCR_IS_PARSING (self));
3170 	g_assert (!self->complete);
3171 	self->complete = TRUE;
3172 	if (async && self->callback != NULL)
3173 		(self->callback) (G_OBJECT (self->parser), G_ASYNC_RESULT (self), self->user_data);
3174 }
3175 
3176 static void
state_failure(GcrParsing * self,gboolean async)3177 state_failure (GcrParsing *self, gboolean async)
3178 {
3179 	g_assert (GCR_IS_PARSING (self));
3180 	g_assert (self->error);
3181 	next_state (self, state_complete);
3182 }
3183 
3184 static void
state_cancelled(GcrParsing * self,gboolean async)3185 state_cancelled (GcrParsing *self, gboolean async)
3186 {
3187 	g_assert (GCR_IS_PARSING (self));
3188 	if (self->cancel && g_cancellable_is_cancelled (self->cancel))
3189 		g_cancellable_cancel (self->cancel);
3190 	if (self->error)
3191 		g_error_free (self->error);
3192 	self->error = g_error_new_literal (GCR_DATA_ERROR, GCR_ERROR_CANCELLED, _("The operation was cancelled"));
3193 	next_state (self, state_failure);
3194 }
3195 
3196 static void
state_parse_buffer(GcrParsing * self,gboolean async)3197 state_parse_buffer (GcrParsing *self, gboolean async)
3198 {
3199 	GError *error = NULL;
3200 	GBytes *bytes;
3201 	gboolean ret;
3202 
3203 	g_assert (GCR_IS_PARSING (self));
3204 	g_assert (self->buffer);
3205 
3206 	bytes = g_byte_array_free_to_bytes (self->buffer);
3207 	self->buffer = NULL;
3208 	ret = gcr_parser_parse_bytes (self->parser, bytes, &error);
3209 	g_bytes_unref (bytes);
3210 
3211 	if (ret == TRUE) {
3212 		next_state (self, state_complete);
3213 	} else {
3214 		g_propagate_error (&self->error, error);
3215 		next_state (self, state_failure);
3216 	}
3217 }
3218 
3219 static void
complete_read_buffer(GcrParsing * self,gssize count,GError * error)3220 complete_read_buffer (GcrParsing *self, gssize count, GError *error)
3221 {
3222 	g_assert (GCR_IS_PARSING (self));
3223 	g_assert (self->buffer);
3224 
3225 	/* A failure */
3226 	if (count == -1) {
3227 		g_propagate_error (&self->error, error);
3228 		next_state (self, state_failure);
3229 	} else {
3230 
3231 		g_return_if_fail (count >= 0 && count <= BLOCK);
3232 		g_byte_array_set_size (self->buffer, self->buffer->len - (BLOCK - count));
3233 
3234 		/* Finished reading */
3235 		if (count == 0)
3236 			next_state (self, state_parse_buffer);
3237 
3238 		/* Read the next block */
3239 		else
3240 			next_state (self, state_read_buffer);
3241 	}
3242 
3243 }
3244 
3245 static void
on_read_buffer(GObject * obj,GAsyncResult * res,gpointer user_data)3246 on_read_buffer (GObject *obj, GAsyncResult *res, gpointer user_data)
3247 {
3248 	GError *error = NULL;
3249 	gssize count;
3250 
3251 	count = g_input_stream_read_finish (G_INPUT_STREAM (obj), res, &error);
3252 	complete_read_buffer (user_data, count, error);
3253 }
3254 
3255 static void
state_read_buffer(GcrParsing * self,gboolean async)3256 state_read_buffer (GcrParsing *self, gboolean async)
3257 {
3258 	GError *error = NULL;
3259 	gssize count;
3260 	gsize at;
3261 
3262 	g_assert (GCR_IS_PARSING (self));
3263 	g_assert (G_IS_INPUT_STREAM (self->input));
3264 
3265 	if (!self->buffer)
3266 		self->buffer = g_byte_array_sized_new (BLOCK);
3267 
3268 	at = self->buffer->len;
3269 	g_byte_array_set_size (self->buffer, at + BLOCK);
3270 
3271 	if (async) {
3272 		g_input_stream_read_async (self->input, self->buffer->data + at,
3273 		                           BLOCK, G_PRIORITY_DEFAULT, self->cancel,
3274 		                           on_read_buffer, self);
3275 	} else {
3276 		count = g_input_stream_read (self->input, self->buffer->data + at,
3277 		                             BLOCK, self->cancel, &error);
3278 		complete_read_buffer (self, count, error);
3279 	}
3280 }
3281 
3282 static void
gcr_parsing_init(GcrParsing * self)3283 gcr_parsing_init (GcrParsing *self)
3284 {
3285 
3286 }
3287 
3288 static void
gcr_parsing_finalize(GObject * obj)3289 gcr_parsing_finalize (GObject *obj)
3290 {
3291 	GcrParsing *self = GCR_PARSING (obj);
3292 
3293 	g_object_unref (self->parser);
3294 	self->parser = NULL;
3295 
3296 	g_object_unref (self->input);
3297 	self->input = NULL;
3298 
3299 	if (self->cancel)
3300 		g_object_unref (self->cancel);
3301 	self->cancel = NULL;
3302 
3303 	g_clear_error (&self->error);
3304 
3305 	if (self->buffer)
3306 		g_byte_array_free (self->buffer, TRUE);
3307 	self->buffer = NULL;
3308 
3309 	G_OBJECT_CLASS (gcr_parsing_parent_class)->finalize (obj);
3310 }
3311 
3312 static void
gcr_parsing_class_init(GcrParsingClass * klass)3313 gcr_parsing_class_init (GcrParsingClass *klass)
3314 {
3315 	G_OBJECT_CLASS (klass)->finalize = gcr_parsing_finalize;
3316 }
3317 
3318 static gpointer
gcr_parsing_real_get_user_data(GAsyncResult * base)3319 gcr_parsing_real_get_user_data (GAsyncResult *base)
3320 {
3321 	g_return_val_if_fail (GCR_IS_PARSING (base), NULL);
3322 	return GCR_PARSING (base)->user_data;
3323 }
3324 
3325 static GObject*
gcr_parsing_real_get_source_object(GAsyncResult * base)3326 gcr_parsing_real_get_source_object (GAsyncResult *base)
3327 {
3328 	g_return_val_if_fail (GCR_IS_PARSING (base), NULL);
3329 	return G_OBJECT (GCR_PARSING (base)->parser);
3330 }
3331 
3332 static void
gcr_parsing_async_result_init(GAsyncResultIface * iface)3333 gcr_parsing_async_result_init (GAsyncResultIface *iface)
3334 {
3335 	iface->get_source_object = gcr_parsing_real_get_source_object;
3336 	iface->get_user_data = gcr_parsing_real_get_user_data;
3337 }
3338 
3339 static GcrParsing*
gcr_parsing_new(GcrParser * parser,GInputStream * input,GCancellable * cancel)3340 gcr_parsing_new (GcrParser *parser, GInputStream *input, GCancellable *cancel)
3341 {
3342 	GcrParsing *self;
3343 
3344 	g_assert (GCR_IS_PARSER (parser));
3345 	g_assert (G_IS_INPUT_STREAM (input));
3346 
3347 	self = g_object_new (GCR_TYPE_PARSING, NULL);
3348 	self->parser = g_object_ref (parser);
3349 	self->input = g_object_ref (input);
3350 	if (cancel)
3351 		self->cancel = g_object_ref (cancel);
3352 
3353 	return self;
3354 }
3355 
3356 /**
3357  * gcr_parser_parse_stream:
3358  * @self: The parser
3359  * @input: The input stream
3360  * @cancellable: An optional cancellation object
3361  * @error: A location to raise an error on failure
3362  *
3363  * Parse items from the data in a #GInputStream. This function may block while
3364  * reading from the input stream. Use gcr_parser_parse_stream_async() for
3365  * a non-blocking variant.
3366  *
3367  * The #GcrParser::parsed and #GcrParser::authenticate signals
3368  * may fire during the parsing.
3369  *
3370  * Returns: Whether the parsing completed successfully or not.
3371  */
3372 gboolean
gcr_parser_parse_stream(GcrParser * self,GInputStream * input,GCancellable * cancellable,GError ** error)3373 gcr_parser_parse_stream (GcrParser *self, GInputStream *input, GCancellable *cancellable,
3374                          GError **error)
3375 {
3376 	GcrParsing *parsing;
3377 	gboolean result;
3378 
3379 	g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
3380 	g_return_val_if_fail (G_IS_INPUT_STREAM (input), FALSE);
3381 	g_return_val_if_fail (!error || !*error, FALSE);
3382 
3383 	parsing = gcr_parsing_new (self, input, cancellable);
3384 	parsing->async = FALSE;
3385 
3386 	next_state (parsing, state_read_buffer);
3387 	g_assert (parsing->complete);
3388 
3389 	result = gcr_parser_parse_stream_finish (self, G_ASYNC_RESULT (parsing), error);
3390 	g_object_unref (parsing);
3391 
3392 	return result;
3393 }
3394 
3395 /**
3396  * gcr_parser_parse_stream_async:
3397  * @self: The parser
3398  * @input: The input stream
3399  * @cancellable: An optional cancellation object
3400  * @callback: Called when the operation result is ready.
3401  * @user_data: Data to pass to callback
3402  *
3403  * Parse items from the data in a #GInputStream. This function completes
3404  * asyncronously and doesn't block.
3405  *
3406  * The #GcrParser::parsed and #GcrParser::authenticate signals
3407  * may fire during the parsing.
3408  */
3409 void
gcr_parser_parse_stream_async(GcrParser * self,GInputStream * input,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)3410 gcr_parser_parse_stream_async (GcrParser *self, GInputStream *input, GCancellable *cancellable,
3411                                GAsyncReadyCallback callback, gpointer user_data)
3412 {
3413 	GcrParsing *parsing;
3414 
3415 	g_return_if_fail (GCR_IS_PARSER (self));
3416 	g_return_if_fail (G_IS_INPUT_STREAM (input));
3417 
3418 	parsing = gcr_parsing_new (self, input, cancellable);
3419 	parsing->async = TRUE;
3420 	parsing->callback = callback;
3421 	parsing->user_data = user_data;
3422 
3423 	next_state (parsing, state_read_buffer);
3424 }
3425 
3426 /**
3427  * gcr_parser_parse_stream_finish:
3428  * @self: The parser
3429  * @result:The operation result
3430  * @error: A location to raise an error on failure
3431  *
3432  * Complete an operation to parse a stream.
3433  *
3434  * Returns: Whether the parsing completed successfully or not.
3435  */
3436 gboolean
gcr_parser_parse_stream_finish(GcrParser * self,GAsyncResult * result,GError ** error)3437 gcr_parser_parse_stream_finish (GcrParser *self, GAsyncResult *result, GError **error)
3438 {
3439 	GcrParsing *parsing;
3440 
3441 	g_return_val_if_fail (GCR_IS_PARSING (result), FALSE);
3442 	g_return_val_if_fail (!error || !*error, FALSE);
3443 
3444 	parsing = GCR_PARSING (result);
3445 	g_return_val_if_fail (parsing->complete, FALSE);
3446 
3447 	if (parsing->error) {
3448 		g_propagate_error (error, parsing->error);
3449 		return FALSE;
3450 	}
3451 
3452 	return TRUE;
3453 }
3454