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