~ubuntu-branches/ubuntu/maverick/gnome-keyring/maverick-proposed

« back to all changes in this revision

Viewing changes to pkix/gkr-pkix-parser.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2008-02-25 10:14:17 UTC
  • mto: (2.2.1 sid)
  • mto: This revision was merged to the branch mainline in revision 49.
  • Revision ID: james.westby@ubuntu.com-20080225101417-wh6qww55r4uiwz7z
Tags: upstream-2.21.92
ImportĀ upstreamĀ versionĀ 2.21.92

Show diffs side-by-side

added added

removed removed

Lines of Context:
141
141
 * HELPERS
142
142
 */
143
143
 
144
 
static const gchar*
145
 
enum_next_password (GkrPkixParser *parser, GQuark loc, gkrid unique, 
146
 
                    GQuark type, const gchar *label, PasswordState *state)
 
144
static gboolean
 
145
enum_next_password (GkrPkixParser *parser, GQuark loc, gkrid digest, 
 
146
                    GQuark type, const gchar *label, PasswordState *state, 
 
147
                    const gchar **password)
147
148
{
148
149
        GkrPkixParserPrivate *pv = GKR_PKIX_PARSER_GET_PRIVATE (parser);
149
150
        gboolean first = FALSE;
150
151
        gchar *display = NULL;
151
 
        gchar *password;
152
152
        guint passes;
 
153
        gchar *prompted;
153
154
        GSList *l;
154
155
 
155
156
        if (gkr_async_is_stopping ())
156
 
                return NULL;
 
157
                return FALSE;
157
158
 
158
159
        /* Is it a new location, reset stuff */
159
160
        if (loc != state->location) {
167
168
        ++state->n_passes;
168
169
                
169
170
        /* 
170
 
         * On the first pass always try an empty password. This helps with 
171
 
         * two things.
 
171
         * On the first pass always try a NULL and then an empty password. 
 
172
         * This helps with two things.
172
173
         *  
173
174
         * 1. Often code will call this function, without actually parsing
174
175
         *    any data yet. So this prevents us prompting the user without
175
176
         *    knowing it will parse. 
176
177
         *  
177
178
         * 2. In case it is actually an empty password, we don't want to 
178
 
         *    prompt the user, just 'decrypt' it.
 
179
         *    prompt the user, just 'decrypt' it. Note that some systems
 
180
         *    use the null password instead of empty, so we try both.
179
181
         */
180
 
        if (passes == 0) 
181
 
                return "";
182
 
                
 
182
        if (passes == 0) {
 
183
                *password = "";
 
184
                return TRUE;
 
185
        }
 
186
        
 
187
        if (passes == 1) {
 
188
                *password = NULL;
 
189
                return TRUE;
 
190
        }
 
191
        
183
192
        /* 
184
193
         * Next passes we look through all the passwords that the parser 
185
194
         * has seen so far. This is because different parts of a encrypted
198
207
        l = state->seen;
199
208
        
200
209
        /* Return first seen password? */
201
 
        if (first && l && l->data)
202
 
                return (const gchar*)l->data;
 
210
        if (first && l && l->data) {
 
211
                *password = (const gchar*)l->data;
 
212
                return TRUE;
 
213
        }
203
214
        
204
215
        /* Return next seen password? */
205
216
        if (l && l->next) {
206
217
                l = state->seen = state->seen->next;
207
 
                if (l->data)
208
 
                        return (const gchar*)l->data;
 
218
                if (l->data) {
 
219
                        *password = (const gchar*)l->data;
 
220
                        return TRUE;
 
221
                }
209
222
        }
210
223
        
211
224
        /* 
217
230
                label = display = gkr_location_to_display (loc);
218
231
        
219
232
        g_signal_emit (parser, signals[ASK_PASSWORD], 0, 
220
 
                       loc, unique, type, label, state->n_prompts, &password);
 
233
                       loc, digest, type, label, state->n_prompts, &prompted);
221
234
                       
222
235
        ++state->n_prompts;
223
236
        g_free (display);
224
237
        
225
238
        /* Stash away any password */
226
 
        if (password)
227
 
                pv->seen_passwords = g_slist_prepend (pv->seen_passwords, password);    
228
 
        return password;
 
239
        if (prompted) {
 
240
                pv->seen_passwords = g_slist_prepend (pv->seen_passwords, prompted);
 
241
                *password = prompted;
 
242
                return TRUE;
 
243
        }
 
244
        
 
245
        return FALSE;
229
246
}
230
247
 
231
248
static void
232
249
fire_parsed_partial (GkrPkixParser *parser, GQuark location, 
233
 
                     gkrconstid unique, GQuark type)
 
250
                     gkrconstid digest, GQuark type)
234
251
{
235
252
        gboolean owned = FALSE;
236
253
        
237
254
        g_assert (location);
238
255
        
239
256
        if (!gkr_async_is_stopping ())
240
 
                g_signal_emit (parser, signals[PARSED_PARTIAL], 0, location, unique, type, &owned);
 
257
                g_signal_emit (parser, signals[PARSED_PARTIAL], 0, location, digest, type, &owned);
241
258
}
242
259
 
243
260
static void
244
 
fire_parsed_sexp (GkrPkixParser *parser, GQuark location, gkrconstid unique, 
 
261
fire_parsed_sexp (GkrPkixParser *parser, GQuark location, gkrconstid digest, 
245
262
                  GQuark type, gcry_sexp_t sexp)
246
263
{
247
264
        gboolean owned = FALSE;
250
267
        g_assert (type);
251
268
        
252
269
        if (!gkr_async_is_stopping ())
253
 
                g_signal_emit (parser, signals[PARSED_SEXP], 0, location, unique, type, sexp, &owned);
 
270
                g_signal_emit (parser, signals[PARSED_SEXP], 0, location, digest, type, sexp, &owned);
254
271
        if (!owned)
255
272
                gcry_sexp_release (sexp);
256
273
}
257
274
 
258
275
static void
259
 
fire_parsed_asn1 (GkrPkixParser *parser, GQuark location, gkrconstid unique, 
 
276
fire_parsed_asn1 (GkrPkixParser *parser, GQuark location, gkrconstid digest, 
260
277
                  GQuark type, ASN1_TYPE asn1)
261
278
{
262
279
        gboolean owned = FALSE;
265
282
        g_assert (type);
266
283
        
267
284
        if (!gkr_async_is_stopping ())
268
 
                g_signal_emit (parser, signals[PARSED_ASN1], 0, location, unique, type, asn1, &owned);
 
285
                g_signal_emit (parser, signals[PARSED_ASN1], 0, location, digest, type, asn1, &owned);
269
286
        if (!owned)
270
287
                asn1_delete_structure (&asn1);
271
288
}
297
314
}
298
315
 
299
316
static gboolean 
300
 
gkr_pkix_parser_parsed_partial (GkrPkixParser *parser, GQuark loc, gkrconstid unique, 
 
317
gkr_pkix_parser_parsed_partial (GkrPkixParser *parser, GQuark loc, gkrconstid digest, 
301
318
                                GQuark type)
302
319
{
303
320
        /* Didn't take ownership of the data */
305
322
}
306
323
 
307
324
static gboolean 
308
 
gkr_pkix_parser_parsed_asn1 (GkrPkixParser *parser, GQuark loc, gkrconstid unique, 
 
325
gkr_pkix_parser_parsed_asn1 (GkrPkixParser *parser, GQuark loc, gkrconstid digest, 
309
326
                             GQuark type, ASN1_TYPE asn1)
310
327
{
311
328
        /* Didn't take ownership of the data */
313
330
}
314
331
 
315
332
static gboolean 
316
 
gkr_pkix_parser_parsed_sexp (GkrPkixParser *parser, GQuark loc, gkrconstid unique, 
 
333
gkr_pkix_parser_parsed_sexp (GkrPkixParser *parser, GQuark loc, gkrconstid digest, 
317
334
                             GQuark type, gcry_sexp_t sexp)
318
335
{
319
336
        /* Didn't take ownership of the data */
321
338
}
322
339
 
323
340
static gchar*
324
 
gkr_pkix_parser_ask_password (GkrPkixParser *parser, GQuark loc, gkrconstid unique,
 
341
gkr_pkix_parser_ask_password (GkrPkixParser *parser, GQuark loc, gkrconstid digest,
325
342
                              GQuark type, const gchar *details, guint n_prompts)
326
343
{
327
344
        return NULL;
478
495
        return ret;
479
496
}
480
497
 
481
 
const gchar*
482
 
gkr_pkix_parsed_type_to_display (GQuark type)
483
 
{
484
 
        if (type == GKR_PKIX_PRIVATE_KEY)
485
 
                return _("private key");
486
 
        else if (type == GKR_PKIX_CERTIFICATE)
487
 
                return _("certificate");
488
 
        else if (type == GKR_PKIX_PUBLIC_KEY)
489
 
                return _("public key");
490
 
        else
491
 
                g_return_val_if_reached ("");
492
 
}
493
 
 
494
498
gboolean
495
499
gkr_pkix_parser_parse_location (GkrPkixParser *parser, GQuark loc, GError **err)
496
500
{
537
541
gkr_pkix_parser_der_private_key (GkrPkixParser *parser, GQuark loc,
538
542
                                 const guchar *data, gsize n_data)
539
543
{
540
 
        gkrid unique;
 
544
        gkrid digest;
541
545
        GkrPkixResult ret;
542
546
        gcry_sexp_t s_key = NULL;
543
547
        
544
 
        unique = gkr_id_new_digest (data, n_data);
 
548
        digest = gkr_id_new_digest (data, n_data);
545
549
        
546
550
        ret = gkr_pkix_der_read_private_key_rsa (data, n_data, &s_key);
547
551
        if (ret == GKR_PKIX_UNRECOGNIZED)
548
552
                ret = gkr_pkix_der_read_private_key_dsa (data, n_data, &s_key);
549
553
        if (ret == GKR_PKIX_SUCCESS)
550
 
                fire_parsed_sexp (parser, loc, unique, GKR_PKIX_PRIVATE_KEY, s_key);
 
554
                fire_parsed_sexp (parser, loc, digest, GKR_PKIX_PRIVATE_KEY, s_key);
551
555
                
552
 
        gkr_id_free (unique);
 
556
        gkr_id_free (digest);
553
557
        
554
558
        return ret;
555
559
}
556
560
 
557
561
static GkrPkixResult
558
562
parse_der_pkcs8_plain (GkrPkixParser *parser, GQuark loc, 
559
 
                       gkrid unique, const guchar *data, gsize n_data)
 
563
                       gkrid digest, const guchar *data, gsize n_data)
560
564
{
561
565
        ASN1_TYPE asn = ASN1_TYPE_EMPTY;
562
566
        GkrPkixResult ret;
622
626
                };
623
627
                
624
628
                if (ret == GKR_PKIX_SUCCESS)
625
 
                        fire_parsed_sexp (parser, loc, unique, GKR_PKIX_PRIVATE_KEY, s_key);
 
629
                        fire_parsed_sexp (parser, loc, digest, GKR_PKIX_PRIVATE_KEY, s_key);
626
630
                
627
631
        } else if (ret == GKR_PKIX_FAILURE) {
628
632
                g_message ("invalid PKCS#8 key");
637
641
gkr_pkix_parser_der_pkcs8_plain (GkrPkixParser *parser, GQuark location, 
638
642
                                 const guchar *data, gsize n_data)
639
643
{
640
 
        gkrid unique;
 
644
        gkrid digest;
641
645
        GkrPkixResult ret;
642
646
        
643
 
        unique = gkr_id_new_digest (data, n_data);
644
 
        ret = parse_der_pkcs8_plain (parser, location, unique, data, n_data);
645
 
        gkr_id_free (unique);
 
647
        digest = gkr_id_new_digest (data, n_data);
 
648
        ret = parse_der_pkcs8_plain (parser, location, digest, data, n_data);
 
649
        gkr_id_free (digest);
646
650
        
647
651
        return ret;
648
652
}
649
653
 
650
654
static GkrPkixResult
651
655
parse_der_pkcs8_encrypted (GkrPkixParser *parser, GQuark location, 
652
 
                           gkrid unique, const guchar *data, gsize n_data)
 
656
                           gkrid digest, const guchar *data, gsize n_data)
653
657
{
654
658
        PasswordState pstate = PASSWORD_STATE_INIT;
655
659
        ASN1_TYPE asn = ASN1_TYPE_EMPTY;
683
687
                
684
688
                g_assert (cih == NULL);
685
689
                
686
 
                password = enum_next_password (parser, location, unique, GKR_PKIX_PRIVATE_KEY, NULL, &pstate);
687
 
 
688
 
                /* If no password is available, we still know it's a key, so 'partial' parse */
689
 
                if (!password) {
690
 
                        fire_parsed_partial (parser, location, unique, GKR_PKIX_PRIVATE_KEY);
691
 
                        ret = GKR_PKIX_SUCCESS;
692
 
                        goto done; 
693
 
                }
 
690
        /* If no password is available, we still know it's a key, so 'partial' parse */
 
691
        if (!enum_next_password (parser, location, digest, GKR_PKIX_PRIVATE_KEY, NULL, &pstate, &password)) {
 
692
                fire_parsed_partial (parser, location, digest, GKR_PKIX_PRIVATE_KEY);
 
693
                ret = GKR_PKIX_SUCCESS;
 
694
                goto done; 
 
695
        }
694
696
                
695
697
                /* 
696
698
                 * Parse the encryption stuff into a cipher. 
724
726
                        n_crypted = l;
725
727
                
726
728
                /* Try to parse the resulting key */
727
 
                r = parse_der_pkcs8_plain (parser, location, unique, crypted, n_crypted);
 
729
                r = parse_der_pkcs8_plain (parser, location, digest, crypted, n_crypted);
728
730
                gkr_secure_free (crypted);
729
731
                crypted = NULL;
730
732
                
750
752
gkr_pkix_parser_der_pkcs8_encrypted (GkrPkixParser *parser, GQuark location, 
751
753
                                     const guchar *data, gsize n_data)
752
754
{
753
 
        gkrid unique;
 
755
        gkrid digest;
754
756
        GkrPkixResult ret;
755
757
        
756
 
        unique = gkr_id_new_digest (data, n_data);
757
 
        ret = parse_der_pkcs8_encrypted (parser, location, unique, data, n_data);
758
 
        gkr_id_free (unique);
 
758
        digest = gkr_id_new_digest (data, n_data);
 
759
        ret = parse_der_pkcs8_encrypted (parser, location, digest, data, n_data);
 
760
        gkr_id_free (digest);
759
761
        
760
762
        return ret;
761
763
}
764
766
gkr_pkix_parser_der_pkcs8 (GkrPkixParser *parser, GQuark loc, const guchar *data, 
765
767
                           gsize n_data)
766
768
{
767
 
        gkrid unique;
 
769
        gkrid digest;
768
770
        GkrPkixResult ret;
769
771
        
770
 
        unique = gkr_id_new_digest (data, n_data);
771
 
        ret = parse_der_pkcs8_plain (parser, loc, unique, data, n_data);
 
772
        digest = gkr_id_new_digest (data, n_data);
 
773
        ret = parse_der_pkcs8_plain (parser, loc, digest, data, n_data);
772
774
        if (ret == GKR_PKIX_UNRECOGNIZED)
773
 
                ret = parse_der_pkcs8_encrypted (parser, loc, unique, data, n_data);
774
 
        gkr_id_free (unique);
 
775
                ret = parse_der_pkcs8_encrypted (parser, loc, digest, data, n_data);
 
776
        gkr_id_free (digest);
775
777
        
776
778
        return ret;
777
779
}
784
786
gkr_pkix_parser_der_certificate (GkrPkixParser *parser, GQuark loc, 
785
787
                                 const guchar *data, gsize n_data)
786
788
{
787
 
        gkrid unique;
 
789
        gkrid digest;
788
790
        GkrPkixResult ret;
789
791
        ASN1_TYPE asn1;
790
792
        
791
 
        unique = gkr_id_new_digest (data, n_data);
 
793
        digest = gkr_id_new_digest (data, n_data);
792
794
 
793
795
        ret = gkr_pkix_der_read_certificate (data, n_data, &asn1);      
794
796
        if(ret == GKR_PKIX_SUCCESS)
795
 
                fire_parsed_asn1 (parser, loc, unique, GKR_PKIX_CERTIFICATE, asn1);
796
 
        gkr_id_free (unique);
 
797
                fire_parsed_asn1 (parser, loc, digest, GKR_PKIX_CERTIFICATE, asn1);
 
798
        gkr_id_free (digest);
797
799
        
798
800
        return ret;
799
801
}
803
805
 */
804
806
 
805
807
static GkrPkixResult
806
 
parse_pkcs12_cert_bag (GkrPkixParser *parser, GQuark loc, gkrid uni, const guchar *data, gsize n_data)
 
808
parse_pkcs12_cert_bag (GkrPkixParser *parser, GQuark loc, gkrid digest, const guchar *data, gsize n_data)
807
809
{
808
810
        ASN1_TYPE asn = ASN1_TYPE_EMPTY;
809
811
        ASN1_TYPE casn = ASN1_TYPE_EMPTY;
833
835
        
834
836
        ret = gkr_pkix_der_read_certificate (certificate, n_certificate, &casn);
835
837
        if(ret == GKR_PKIX_SUCCESS)
836
 
                fire_parsed_asn1 (parser, loc, uni, GKR_PKIX_CERTIFICATE, casn);
 
838
                fire_parsed_asn1 (parser, loc, digest, GKR_PKIX_CERTIFICATE, casn);
837
839
                
838
840
done:
839
841
        if (asn)
843
845
}
844
846
 
845
847
static GkrPkixResult
846
 
parse_pkcs12_bag (GkrPkixParser *parser, GQuark loc, gkrid uni, const guchar *data, gsize n_data)
 
848
parse_pkcs12_bag (GkrPkixParser *parser, GQuark loc, gkrid digest, const guchar *data, gsize n_data)
847
849
{
848
850
        ASN1_TYPE asn = ASN1_TYPE_EMPTY;
849
851
        GkrPkixResult ret, r;
850
 
        int count = 0;
 
852
        int res, count = 0;
851
853
        GQuark oid;
852
 
        gchar *part;
853
854
        const guchar *element;
854
855
        gsize n_element;
855
 
        int res, i;
856
856
        
857
857
        ret = GKR_PKIX_UNRECOGNIZED;
858
858
        
870
870
        /* 
871
871
         * Now inside each bag are multiple elements. Who comes up 
872
872
         * with this stuff?
 
873
         * 
 
874
         * But this is where we draw the line. We only support one
 
875
         * element per bag, not multiple elements, not strange
 
876
         * nested bags, not fairy queens with magical wands in bags...
 
877
         * 
 
878
         * Just one element per bag.
873
879
         */
874
 
        for (i = 0; i < count; ++i)
875
 
        {
876
 
                part = g_strdup_printf ("?%u.bagId", i + 1);
877
 
                oid = gkr_pkix_asn1_read_oid (asn, part);
878
 
                g_free (part);
879
 
                
 
880
        if (count >= 1) {
 
881
 
 
882
                oid = gkr_pkix_asn1_read_oid (asn, "?1.bagId");
880
883
                if (!oid)
881
884
                        goto done;
882
885
                
883
 
                part = g_strdup_printf ("?%u.bagValue", i + 1);
884
 
                element = gkr_pkix_asn1_read_content (asn, data, n_data, part, &n_element);     
885
 
                g_free (part);
886
 
        
 
886
                element = gkr_pkix_asn1_read_content (asn, data, n_data, "?1.bagValue", &n_element);    
887
887
                if (!element)
888
888
                        goto done;
889
889
 
890
890
                /* A normal unencrypted key */
891
891
                if (oid == OID_PKCS12_BAG_PKCS8_KEY) {
892
 
                        r = parse_der_pkcs8_plain (parser, loc, uni, element, n_element);
 
892
                        r = parse_der_pkcs8_plain (parser, loc, digest, element, n_element);
893
893
                        
894
894
                /* A properly encrypted key */
895
895
                } else if (oid == OID_PKCS12_BAG_PKCS8_ENCRYPTED_KEY) {
896
 
                        r = parse_der_pkcs8_encrypted (parser, loc, uni, element, n_element);
 
896
                        r = parse_der_pkcs8_encrypted (parser, loc, digest, element, n_element);
897
897
                        
898
898
                /* A certificate */
899
899
                } else if (oid == OID_PKCS12_BAG_CERTIFICATE) {
900
 
                        r = parse_pkcs12_cert_bag (parser, loc, uni, element, n_element);
 
900
                        r = parse_pkcs12_cert_bag (parser, loc, digest, element, n_element);
901
901
                                                                
902
902
                /* TODO: OID_PKCS12_BAG_CRL */
903
903
                } else {
920
920
}
921
921
 
922
922
static GkrPkixResult
923
 
parse_pkcs12_encrypted_bag (GkrPkixParser *parser, GQuark loc, gkrid uni, 
 
923
parse_pkcs12_encrypted_bag (GkrPkixParser *parser, GQuark loc, gkrid digest, 
924
924
                            const guchar *data, gsize n_data)
925
925
{
926
926
        PasswordState pstate = PASSWORD_STATE_INIT;
957
957
                
958
958
                g_assert (cih == NULL);
959
959
                
960
 
                password = enum_next_password (parser, loc, uni, 0, NULL, &pstate);
961
 
                if (!password) {
962
 
                        fire_parsed_partial (parser, loc, uni, 0);
 
960
                if (!enum_next_password (parser, loc, digest, 0, NULL, &pstate, &password)) {
 
961
                        fire_parsed_partial (parser, loc, digest, 0);
963
962
                        ret = GKR_PKIX_SUCCESS;
964
963
                        goto done; 
965
964
                }
994
993
                        n_crypted = l;
995
994
 
996
995
                /* Try to parse the resulting key */
997
 
                r = parse_pkcs12_bag (parser, loc, uni, crypted, n_crypted);
 
996
                r = parse_pkcs12_bag (parser, loc, digest, crypted, n_crypted);
998
997
                gkr_secure_free (crypted);
999
998
                crypted = NULL;
1000
999
                
1022
1021
        ASN1_TYPE asn = ASN1_TYPE_EMPTY;
1023
1022
        GkrPkixResult ret, r;
1024
1023
        const guchar *bag;
1025
 
        gkrid uni = NULL;
 
1024
        gkrid digest = NULL;
1026
1025
        gsize n_bag;
1027
1026
        gchar *part;
1028
1027
        GQuark oid;
1056
1055
                if (!bag) /* A parse error */
1057
1056
                        goto done;
1058
1057
                        
1059
 
                gkr_id_free (uni);
1060
 
                uni = gkr_id_new_digest (bag, n_bag);
 
1058
                gkr_id_free (digest);
 
1059
                digest = gkr_id_new_digest (bag, n_bag);
1061
1060
                        
1062
1061
                /* A non encrypted bag, just parse */
1063
1062
                if (oid == OID_PKCS7_DATA) {
1070
1069
                        if (!bag)
1071
1070
                                goto done;      
1072
1071
                        
1073
 
                        r = parse_pkcs12_bag (parser, loc, uni, bag, n_bag);
 
1072
                        r = parse_pkcs12_bag (parser, loc, digest, bag, n_bag);
1074
1073
 
1075
1074
                /* Encrypted data first needs decryption */
1076
1075
                } else if (oid == OID_PKCS7_ENCRYPTED_DATA) {
1077
 
                        r = parse_pkcs12_encrypted_bag (parser, loc, uni, bag, n_bag);
 
1076
                        r = parse_pkcs12_encrypted_bag (parser, loc, digest, bag, n_bag);
1078
1077
                
1079
1078
                /* Hmmmm, not sure what this is */
1080
1079
                } else {
1093
1092
done:
1094
1093
        if (asn)
1095
1094
                asn1_delete_structure (&asn);
1096
 
        if (uni)
1097
 
                gkr_id_free (uni);
 
1095
        if (digest)
 
1096
                gkr_id_free (digest);
1098
1097
                
1099
1098
        return ret;
1100
1099
}
1145
1144
}
1146
1145
 
1147
1146
static GkrPkixResult
1148
 
parse_pkcs7_signed_data (GkrPkixParser *parser, GQuark loc, gkrid uni, 
 
1147
parse_pkcs7_signed_data (GkrPkixParser *parser, GQuark loc, gkrid digest, 
1149
1148
                         const guchar *data, gsize n_data)
1150
1149
{
1151
1150
        ASN1_TYPE asn = ASN1_TYPE_EMPTY;
1176
1175
        
1177
1176
                ret = gkr_pkix_der_read_certificate (certificate, n_certificate, &casn);
1178
1177
                if (ret == GKR_PKIX_SUCCESS)
1179
 
                        fire_parsed_asn1 (parser, loc, uni, GKR_PKIX_CERTIFICATE, casn);
 
1178
                        fire_parsed_asn1 (parser, loc, digest, GKR_PKIX_CERTIFICATE, casn);
1180
1179
                if (ret == GKR_PKIX_FAILURE)
1181
1180
                        goto done;
1182
1181
        }
1192
1191
}
1193
1192
 
1194
1193
static GkrPkixResult
1195
 
parse_der_pkcs7 (GkrPkixParser *parser, GQuark loc, gkrid uni, 
 
1194
parse_der_pkcs7 (GkrPkixParser *parser, GQuark loc, gkrid digest, 
1196
1195
                 const guchar *data, gsize n_data)
1197
1196
{
1198
1197
        ASN1_TYPE asn = ASN1_TYPE_EMPTY;
1223
1222
        if (!content) 
1224
1223
                goto done;
1225
1224
                
1226
 
        ret = parse_pkcs7_signed_data (parser, loc, uni, content, n_content);
 
1225
        ret = parse_pkcs7_signed_data (parser, loc, digest, content, n_content);
1227
1226
                        
1228
1227
done:
1229
1228
        if (asn)
1235
1234
gkr_pkix_parser_der_pkcs7 (GkrPkixParser *parser, GQuark loc, const guchar *data, gsize n_data)
1236
1235
{
1237
1236
        GkrPkixResult ret;
1238
 
        gkrid uni;
 
1237
        gkrid digest;
1239
1238
        
1240
 
        uni = gkr_id_new_digest (data, n_data);
1241
 
        ret = parse_der_pkcs7 (parser, loc, uni, data, n_data);
1242
 
        gkr_id_free (uni);
 
1239
        digest = gkr_id_new_digest (data, n_data);
 
1240
        ret = parse_der_pkcs7 (parser, loc, digest, data, n_data);
 
1241
        gkr_id_free (digest);
1243
1242
        
1244
1243
        return ret;
1245
1244
}
1271
1270
}
1272
1271
 
1273
1272
static GkrPkixResult
1274
 
parse_plain_pem (GkrPkixParser *parser, GQuark location, gkrid unique, 
 
1273
parse_plain_pem (GkrPkixParser *parser, GQuark location, gkrid digest, 
1275
1274
                 GQuark type, const guchar *data, gsize n_data)
1276
1275
{
1277
1276
        GkrPkixResult res;
1292
1291
                res = gkr_pkix_der_read_private_key (data, n_data, &s_key);
1293
1292
        
1294
1293
        } else if (type == PEM_PRIVATE_KEY) {
1295
 
                return parse_der_pkcs8_plain (parser, location, unique, data, n_data);
 
1294
                return parse_der_pkcs8_plain (parser, location, digest, data, n_data);
1296
1295
                
1297
1296
        } else if (type == PEM_ENCRYPTED_PRIVATE_KEY) {
1298
 
                return parse_der_pkcs8_encrypted (parser, location, unique, data, n_data);
 
1297
                return parse_der_pkcs8_encrypted (parser, location, digest, data, n_data);
1299
1298
                
1300
1299
        } else if (type == PEM_CERTIFICATE) {
1301
1300
                parsed = GKR_PKIX_CERTIFICATE;
1302
1301
                res = gkr_pkix_der_read_certificate (data, n_data, &asn1);
1303
1302
                
1304
1303
        } else if (type == PEM_PKCS7) {
1305
 
                return parse_der_pkcs7 (parser, location, unique, data, n_data);
 
1304
                return parse_der_pkcs7 (parser, location, digest, data, n_data);
1306
1305
                
1307
1306
        } else if (type == PEM_PKCS7) {
1308
1307
                return gkr_pkix_parser_der_pkcs12 (parser, location, data, n_data);
1316
1315
                g_assert (parsed);
1317
1316
                
1318
1317
                if (s_key)
1319
 
                        fire_parsed_sexp (parser, location, unique, parsed, s_key);
 
1318
                        fire_parsed_sexp (parser, location, digest, parsed, s_key);
1320
1319
                else
1321
 
                        fire_parsed_asn1 (parser, location, unique, parsed, asn1);
 
1320
                        fire_parsed_asn1 (parser, location, digest, parsed, asn1);
1322
1321
        }
1323
1322
 
1324
1323
        return res;
1325
1324
}
1326
1325
 
1327
1326
static GkrPkixResult
1328
 
parse_encrypted_pem (GkrPkixParser *parser, GQuark location, gkrid unique, 
 
1327
parse_encrypted_pem (GkrPkixParser *parser, GQuark location, gkrid digest, 
1329
1328
                     GQuark type, GHashTable *headers, const guchar *data, gsize n_data)
1330
1329
{
1331
1330
        PasswordState pstate = PASSWORD_STATE_INIT;
1354
1353
                
1355
1354
        while (!gkr_async_is_stopping ()) {
1356
1355
 
1357
 
                password = enum_next_password (parser, location, unique, parsed, NULL, &pstate);
1358
 
 
1359
 
                /* If no password is available, we still know what it was, so 'partial' parse */
1360
 
                if (!password) {
1361
 
                        fire_parsed_partial (parser, location, unique, parsed);
1362
 
                        return GKR_PKIX_SUCCESS;
1363
 
                }
 
1356
        /* If no password is available, we still know what it was, so 'partial' parse */
 
1357
                if (!enum_next_password (parser, location, digest, parsed, NULL, &pstate, &password)) {
 
1358
                fire_parsed_partial (parser, location, digest, parsed);
 
1359
                return GKR_PKIX_SUCCESS;
 
1360
        }
1364
1361
                
1365
1362
                decrypted = NULL;
1366
1363
                n_decrypted = 0;
1379
1376
                        n_decrypted = l;
1380
1377
        
1381
1378
                /* Try to parse */
1382
 
                ret = parse_plain_pem (parser, location, unique, type, decrypted, n_decrypted);
 
1379
                ret = parse_plain_pem (parser, location, digest, type, decrypted, n_decrypted);
1383
1380
                gkr_secure_free (decrypted);
1384
1381
 
1385
1382
                if (ret != GKR_PKIX_UNRECOGNIZED)
1396
1393
        ParserCtx *ctx = (ParserCtx*)user_data;
1397
1394
        GkrPkixResult res = GKR_PKIX_FAILURE;
1398
1395
        gboolean encrypted = FALSE;
1399
 
        gkrid unique;
 
1396
        gkrid digest;
1400
1397
        const gchar *val;
1401
1398
        
1402
 
        unique = gkr_id_new_digest (data, n_data);
 
1399
        digest = gkr_id_new_digest (data, n_data);
1403
1400
 
1404
1401
        /* See if it's encrypted PEM all openssl like*/
1405
1402
        if (headers) {
1409
1406
        }
1410
1407
        
1411
1408
        if (encrypted) {
1412
 
                res = parse_encrypted_pem (ctx->parser, ctx->location, unique,
 
1409
                res = parse_encrypted_pem (ctx->parser, ctx->location, digest,
1413
1410
                                           type, headers, data, n_data); 
1414
1411
        } else {
1415
 
                res = parse_plain_pem (ctx->parser, ctx->location, unique, 
 
1412
                res = parse_plain_pem (ctx->parser, ctx->location, digest, 
1416
1413
                                       type, data, n_data);
1417
1414
        }
1418
1415
        
1421
1418
        } else if (ctx->result == GKR_PKIX_UNRECOGNIZED)
1422
1419
                ctx->result = res;
1423
1420
                
1424
 
        gkr_id_free (unique);
 
1421
        gkr_id_free (digest);
1425
1422
}
1426
1423
 
1427
1424
GkrPkixResult