"Fossies" - the Fresh Open Source Software Archive 
Member "libksba-1.5.0/src/cms-parser.c" (18 Nov 2020, 29049 Bytes) of package /linux/privat/libksba-1.5.0.tar.bz2:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "cms-parser.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
1.4.0_vs_1.5.0.
1 /* cms-parse.c - parse cryptographic message syntax
2 * Copyright (C) 2001, 2012 g10 Code GmbH
3 *
4 * This file is part of KSBA.
5 *
6 * KSBA is free software; you can redistribute it and/or modify
7 * it under the terms of either
8 *
9 * - the GNU Lesser General Public License as published by the Free
10 * Software Foundation; either version 3 of the License, or (at
11 * your option) any later version.
12 *
13 * or
14 *
15 * - the GNU General Public License as published by the Free
16 * Software Foundation; either version 2 of the License, or (at
17 * your option) any later version.
18 *
19 * or both in parallel, as here.
20 *
21 * KSBA is distributed in the hope that it will be useful, but WITHOUT
22 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
24 * License for more details.
25 *
26 * You should have received a copies of the GNU General Public License
27 * and the GNU Lesser General Public License along with this program;
28 * if not, see <http://www.gnu.org/licenses/>.
29 */
30
31 /*
32 We handle CMS by using a handcrafted parser for the outer
33 structures and the generic parser of the parts we can handle in
34 memory. Extending the generic parser to allow hooks for indefinite
35 length objects and to auto select the object depending on the
36 content type OID is too complicated.
37 */
38
39
40 #include <config.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <assert.h>
45 #include "util.h"
46
47 #include "cms.h"
48 #include "asn1-func.h" /* need some constants */
49 #include "ber-decoder.h"
50 #include "ber-help.h"
51 #include "keyinfo.h"
52
53 static int
54 read_byte (ksba_reader_t reader)
55 {
56 unsigned char buf;
57 size_t nread;
58 int rc;
59
60 do
61 rc = ksba_reader_read (reader, &buf, 1, &nread);
62 while (!rc && !nread);
63 return rc? -1: buf;
64 }
65
66 /* read COUNT bytes into buffer. Return 0 on success */
67 static int
68 read_buffer (ksba_reader_t reader, char *buffer, size_t count)
69 {
70 size_t nread;
71
72 while (count)
73 {
74 if (ksba_reader_read (reader, buffer, count, &nread))
75 return -1;
76 buffer += nread;
77 count -= nread;
78 }
79 return 0;
80 }
81
82 /* Create a new decoder and run it for the given element */
83 static gpg_error_t
84 create_and_run_decoder (ksba_reader_t reader, const char *elem_name,
85 unsigned int flags,
86 AsnNode *r_root,
87 unsigned char **r_image, size_t *r_imagelen)
88 {
89 gpg_error_t err;
90 ksba_asn_tree_t cms_tree;
91 BerDecoder decoder;
92
93 err = ksba_asn_create_tree ("cms", &cms_tree);
94 if (err)
95 return err;
96
97 decoder = _ksba_ber_decoder_new ();
98 if (!decoder)
99 {
100 ksba_asn_tree_release (cms_tree);
101 return gpg_error (GPG_ERR_ENOMEM);
102 }
103
104 err = _ksba_ber_decoder_set_reader (decoder, reader);
105 if (err)
106 {
107 ksba_asn_tree_release (cms_tree);
108 _ksba_ber_decoder_release (decoder);
109 return err;
110 }
111
112 err = _ksba_ber_decoder_set_module (decoder, cms_tree);
113 if (err)
114 {
115 ksba_asn_tree_release (cms_tree);
116 _ksba_ber_decoder_release (decoder);
117 return err;
118 }
119
120 err = _ksba_ber_decoder_decode (decoder, elem_name, flags,
121 r_root, r_image, r_imagelen);
122
123 _ksba_ber_decoder_release (decoder);
124 ksba_asn_tree_release (cms_tree);
125 return err;
126 }
127
128
129
130 /* Parse this structure and return the oid of the content. The read
131 position is then located at the value of content. This fucntion is
132 the core for parsing ContentInfo and EncapsulatedContentInfo.
133
134 ContentInfo ::= SEQUENCE {
135 contentType ContentType,
136 content [0] EXPLICIT ANY DEFINED BY contentType
137 }
138 ContentType ::= OBJECT IDENTIFIER
139
140 Returns: 0 on success or an error code. Other values are returned
141 by the parameters.
142
143 */
144 static gpg_error_t
145 parse_content_info (ksba_reader_t reader,
146 unsigned long *r_len, int *r_ndef,
147 char **r_oid, int *has_content)
148 {
149 struct tag_info ti;
150 gpg_error_t err;
151 int content_ndef;
152 unsigned long content_len;
153 unsigned char oidbuf[100]; /* pretty large for an OID */
154 char *oid = NULL;
155
156 /* read the sequence triplet */
157 err = _ksba_ber_read_tl (reader, &ti);
158 if (err)
159 return err;
160 if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
161 && ti.is_constructed) )
162 return gpg_error (GPG_ERR_INV_CMS_OBJ);
163 content_len = ti.length;
164 content_ndef = ti.ndef;
165 if (!content_ndef && content_len < 3)
166 return gpg_error (GPG_ERR_TOO_SHORT); /* to encode an OID */
167
168 /* read the OID */
169 err = _ksba_ber_read_tl (reader, &ti);
170 if (err)
171 return err;
172 if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID
173 && !ti.is_constructed && ti.length) )
174 return gpg_error (GPG_ERR_INV_CMS_OBJ);
175 if (!content_ndef)
176 {
177 if (content_len < ti.nhdr)
178 return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
179 content_len -= ti.nhdr;
180 if (content_len < ti.length)
181 return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
182 content_len -= ti.length;
183 }
184
185 if (ti.length >= DIM(oidbuf))
186 return gpg_error (GPG_ERR_TOO_LARGE);
187 err = read_buffer (reader, oidbuf, ti.length);
188 if (err)
189 return err;
190 oid = ksba_oid_to_str (oidbuf, ti.length);
191 if (!oid)
192 return gpg_error (GPG_ERR_ENOMEM);
193
194 if (!content_ndef && !content_len)
195 { /* no data */
196 *has_content = 0;
197 }
198 else
199 { /* now read the explicit tag 0 which is optional */
200 err = _ksba_ber_read_tl (reader, &ti);
201 if (err)
202 {
203 xfree (oid);
204 return err;
205 }
206
207 if ( ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed )
208 {
209 *has_content = 1;
210 }
211 else if ( ti.class == CLASS_UNIVERSAL && ti.tag == 0 && !ti.is_constructed )
212 {
213 *has_content = 0; /* this is optional - allow NUL tag */
214 }
215 else /* neither [0] nor NULL */
216 {
217 xfree (oid);
218 return gpg_error (GPG_ERR_INV_CMS_OBJ);
219 }
220 if (!content_ndef)
221 {
222 if (content_len < ti.nhdr)
223 return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
224 content_len -= ti.nhdr;
225 if (!ti.ndef && content_len < ti.length)
226 return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
227 }
228 }
229 *r_len = content_len;
230 *r_ndef = content_ndef;
231 *r_oid = oid;
232 return 0;
233 }
234
235
236 /* Parse this structure and return the oid of the content as well as
237 the algorithm identifier. The read position is then located at the
238 value of the octect string.
239
240 EncryptedContentInfo ::= SEQUENCE {
241 contentType OBJECT IDENTIFIER,
242 contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
243 encryptedContent [0] IMPLICIT OCTET STRING OPTIONAL }
244
245 Returns: 0 on success or an error code. Other values are returned
246 by the parameters.
247 */
248 static gpg_error_t
249 parse_encrypted_content_info (ksba_reader_t reader,
250 unsigned long *r_len, int *r_ndef,
251 char **r_cont_oid, char **r_algo_oid,
252 char **r_algo_parm, size_t *r_algo_parmlen,
253 int *has_content)
254 {
255 struct tag_info ti;
256 gpg_error_t err;
257 int content_ndef;
258 unsigned long content_len;
259 unsigned char tmpbuf[500]; /* for OID or algorithmIdentifier */
260 char *cont_oid = NULL;
261 char *algo_oid = NULL;
262 char *algo_parm = NULL;
263 size_t algo_parmlen;
264 size_t nread;
265
266 /* Fixme: release oids in case of errors */
267
268 /* read the sequence triplet */
269 err = _ksba_ber_read_tl (reader, &ti);
270 if (err)
271 return err;
272 if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
273 && ti.is_constructed) )
274 return gpg_error (GPG_ERR_INV_CMS_OBJ);
275 content_len = ti.length;
276 content_ndef = ti.ndef;
277 if (!content_ndef && content_len < 3)
278 return gpg_error (GPG_ERR_TOO_SHORT); /* to encode an OID */
279
280 /* read the OID */
281 err = _ksba_ber_read_tl (reader, &ti);
282 if (err)
283 return err;
284 if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID
285 && !ti.is_constructed && ti.length) )
286 return gpg_error (GPG_ERR_INV_CMS_OBJ);
287 if (!content_ndef)
288 {
289 if (content_len < ti.nhdr)
290 return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
291 content_len -= ti.nhdr;
292 if (content_len < ti.length)
293 return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
294 content_len -= ti.length;
295 }
296 if (ti.length >= DIM(tmpbuf))
297 return gpg_error (GPG_ERR_TOO_LARGE);
298 err = read_buffer (reader, tmpbuf, ti.length);
299 if (err)
300 return err;
301 cont_oid = ksba_oid_to_str (tmpbuf, ti.length);
302 if (!cont_oid)
303 return gpg_error (GPG_ERR_ENOMEM);
304
305 /* read the algorithmIdentifier */
306 err = _ksba_ber_read_tl (reader, &ti);
307 if (err)
308 return err;
309 if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
310 && ti.is_constructed) )
311 return gpg_error (GPG_ERR_INV_CMS_OBJ);
312 if (!content_ndef)
313 {
314 if (content_len < ti.nhdr)
315 return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
316 content_len -= ti.nhdr;
317 if (content_len < ti.length)
318 return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
319 content_len -= ti.length;
320 }
321 if (ti.nhdr + ti.length >= DIM(tmpbuf))
322 return gpg_error (GPG_ERR_TOO_LARGE);
323 memcpy (tmpbuf, ti.buf, ti.nhdr);
324 err = read_buffer (reader, tmpbuf+ti.nhdr, ti.length);
325 if (err)
326 return err;
327 err = _ksba_parse_algorithm_identifier2 (tmpbuf, ti.nhdr+ti.length,
328 &nread,&algo_oid,
329 &algo_parm, &algo_parmlen);
330 if (err)
331 return err;
332 assert (nread <= ti.nhdr + ti.length);
333 if (nread < ti.nhdr + ti.length)
334 return gpg_error (GPG_ERR_TOO_SHORT);
335
336 /* the optional encryptedDataInfo */
337 *has_content = 0;
338 if (content_ndef || content_len)
339 { /* now read the implicit tag 0. Actually this is optional but
340 in that case we don't expect to have a content_len - well, it
341 may be the end tag */
342 err = _ksba_ber_read_tl (reader, &ti);
343 if (err)
344 {
345 xfree (cont_oid);
346 xfree (algo_oid);
347 return err;
348 }
349
350 /* Note: the tag may either denote a constructed or a primitve
351 object. Actually this should match the use of NDEF header
352 but we don't ceck that */
353 if ( ti.class == CLASS_CONTEXT && ti.tag == 0 )
354 {
355 *has_content = 1;
356 if (!content_ndef)
357 {
358 if (content_len < ti.nhdr)
359 return gpg_error (GPG_ERR_BAD_BER);
360 content_len -= ti.nhdr;
361 if (!ti.ndef && content_len < ti.length)
362 return gpg_error (GPG_ERR_BAD_BER);
363 }
364 }
365 else /* not what we want - push it back */
366 {
367 *has_content = 0;
368 err = ksba_reader_unread (reader, ti.buf, ti.nhdr);
369 if (err)
370 return err;
371 }
372 }
373 *r_len = content_len;
374 *r_ndef = content_ndef;
375 *r_cont_oid = cont_oid;
376 *r_algo_oid = algo_oid;
377 *r_algo_parm = algo_parm;
378 *r_algo_parmlen = algo_parmlen;
379 return 0;
380 }
381
382
383
384 /* Parse this structure and return the oid of the content. The read
385 position is then located at the value of content.
386
387 ContentInfo ::= SEQUENCE {
388 contentType ContentType,
389 content [0] EXPLICIT ANY DEFINED BY contentType
390 }
391 ContentType ::= OBJECT IDENTIFIER
392
393 Returns: 0 on success or an error code. On success the OID and the
394 length values are stored in the cms structure.
395 */
396 gpg_error_t
397 _ksba_cms_parse_content_info (ksba_cms_t cms)
398 {
399 gpg_error_t err;
400 int has_content;
401 int content_ndef;
402 unsigned long content_len;
403 char *oid;
404
405 err = parse_content_info (cms->reader, &content_len, &content_ndef,
406 &oid, &has_content);
407 if (err)
408 { /* return a more meaningful error message. This way the caller
409 can pass arbitrary data to the function and get back an error
410 that this is not CMS instead of the the not very detailed BER
411 Error. */
412 if (gpg_err_code (err) == GPG_ERR_BAD_BER
413 || gpg_err_code (err) == GPG_ERR_INV_CMS_OBJ
414 || gpg_err_code (err) == GPG_ERR_TOO_SHORT)
415 err = gpg_error (GPG_ERR_NO_CMS_OBJ);
416 return err;
417 }
418 if (!has_content)
419 return gpg_error (GPG_ERR_NO_CMS_OBJ); /* It is not optional here */
420 cms->content.length = content_len;
421 cms->content.ndef = content_ndef;
422 xfree (cms->content.oid);
423 cms->content.oid = oid;
424 return 0;
425 }
426
427
428
429 /* parse a SEQUENCE and the first element which is expected to be the
430 CMS version. Return the version and the length info */
431 static gpg_error_t
432 parse_cms_version (ksba_reader_t reader, int *r_version,
433 unsigned long *r_len, int *r_ndef)
434 {
435 struct tag_info ti;
436 gpg_error_t err;
437 unsigned long data_len;
438 int data_ndef;
439 int c;
440
441 /* read the sequence triplet */
442 err = _ksba_ber_read_tl (reader, &ti);
443 if (err)
444 return err;
445 if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
446 && ti.is_constructed) )
447 return gpg_error (GPG_ERR_INV_CMS_OBJ);
448 data_len = ti.length;
449 data_ndef = ti.ndef;
450 if (!data_ndef && data_len < 3)
451 return gpg_error (GPG_ERR_TOO_SHORT); /*to encode the version*/
452
453 /* read the version integer */
454 err = _ksba_ber_read_tl (reader, &ti);
455 if (err)
456 return err;
457 if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_INTEGER
458 && !ti.is_constructed && ti.length) )
459 return gpg_error (GPG_ERR_INV_CMS_OBJ);
460 if (!data_ndef)
461 {
462 if (data_len < ti.nhdr)
463 return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
464 data_len -= ti.nhdr;
465 if (data_len < ti.length)
466 return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
467 data_len -= ti.length;
468 }
469 if (ti.length != 1)
470 return gpg_error (GPG_ERR_UNSUPPORTED_CMS_VERSION);
471 if ( (c=read_byte (reader)) == -1)
472 {
473 err = ksba_reader_error (reader);
474 return err? err : gpg_error (GPG_ERR_GENERAL);
475 }
476 if ( !(c == 0 || c == 1 || c == 2 || c == 3 || c == 4) )
477 return gpg_error (GPG_ERR_UNSUPPORTED_CMS_VERSION);
478 *r_version = c;
479 *r_len = data_len;
480 *r_ndef = data_ndef;
481 return 0;
482 }
483
484
485
486
487 /* Parse a structure:
488
489 SignedData ::= SEQUENCE {
490 version INTEGER { v0(0), v1(1), v2(2), v3(3), v4(4) }),
491 digestAlgorithms SET OF AlgorithmIdentifier,
492 encapContentInfo EncapsulatedContentInfo,
493 certificates [0] IMPLICIT CertificateSet OPTIONAL,
494 crls [1] IMPLICIT CertificateRevocationLists OPTIONAL,
495 signerInfos SignerInfos }
496
497 AlgorithmIdentifier ::= SEQUENCE {
498 algorithm OBJECT IDENTIFIER,
499 parameters ANY DEFINED BY algorithm OPTIONAL
500 }
501
502 */
503 gpg_error_t
504 _ksba_cms_parse_signed_data_part_1 (ksba_cms_t cms)
505 {
506 struct tag_info ti;
507 gpg_error_t err;
508 int signed_data_ndef;
509 unsigned long signed_data_len;
510 int algo_set_ndef;
511 unsigned long algo_set_len;
512 int encap_cont_ndef;
513 unsigned long encap_cont_len;
514 int has_content;
515 char *oid;
516 char *p, *buffer;
517 unsigned long off, len;
518
519 err = parse_cms_version (cms->reader, &cms->cms_version,
520 &signed_data_len, &signed_data_ndef);
521 if (err)
522 return err;
523
524 /* read the SET OF algorithmIdentifiers */
525 err = _ksba_ber_read_tl (cms->reader, &ti);
526 if (err)
527 return err;
528 if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SET
529 && ti.is_constructed) )
530 return gpg_error (GPG_ERR_INV_CMS_OBJ); /* not the expected SET tag */
531 if (!signed_data_ndef)
532 {
533 if (signed_data_len < ti.nhdr)
534 return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
535 signed_data_len -= ti.nhdr;
536 if (!ti.ndef && signed_data_len < ti.length)
537 return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
538 signed_data_len -= ti.length;
539 }
540 algo_set_len = ti.length;
541 algo_set_ndef = ti.ndef;
542
543 /* fixme: we are not able to read ndef length algorithm indentifiers. */
544 if (algo_set_ndef)
545 return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
546 /* read the entire sequence into a buffer (add one to avoid malloc(0)) */
547 buffer = xtrymalloc (algo_set_len + 1);
548 if (!buffer)
549 return gpg_error (GPG_ERR_ENOMEM);
550 if (read_buffer (cms->reader, buffer, algo_set_len))
551 {
552 xfree (buffer);
553 err = ksba_reader_error (cms->reader);
554 return err? err: gpg_error (GPG_ERR_GENERAL);
555 }
556 p = buffer;
557 while (algo_set_len)
558 {
559 size_t nread;
560 struct oidlist_s *ol;
561
562 err = _ksba_parse_algorithm_identifier (p, algo_set_len, &nread, &oid);
563 if (err)
564 {
565 xfree (buffer);
566 return err;
567 }
568 assert (nread <= algo_set_len);
569 algo_set_len -= nread;
570 p += nread;
571 /* store the oid */
572 ol = xtrymalloc (sizeof *ol);
573 if (!ol)
574 {
575 xfree (oid);
576 return gpg_error (GPG_ERR_ENOMEM);
577 }
578 ol->oid = oid;
579 ol->next = cms->digest_algos;
580 cms->digest_algos = ol;
581 }
582 xfree (buffer); buffer = NULL;
583
584 /* Now for the encapsulatedContentInfo */
585 off = ksba_reader_tell (cms->reader);
586 err = parse_content_info (cms->reader,
587 &encap_cont_len, &encap_cont_ndef,
588 &oid, &has_content);
589 if (err)
590 return err;
591 cms->inner_cont_len = encap_cont_len;
592 cms->inner_cont_ndef = encap_cont_ndef;
593 cms->inner_cont_oid = oid;
594 cms->detached_data = !has_content;
595 if (!signed_data_ndef)
596 {
597 len = ksba_reader_tell (cms->reader) - off;
598 if (signed_data_len < len)
599 return gpg_error (GPG_ERR_BAD_BER); /* parsed content info larger that sequence */
600 signed_data_len -= len;
601 if (!encap_cont_ndef && signed_data_len < encap_cont_len)
602 return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
603 }
604
605 /* We have to stop here so that the caller can set up the hashing etc. */
606 return 0;
607 }
608
609 /* Continue parsing of the structure we started to parse with the
610 part_1 function. We expect to be right at the certificates tag. */
611 gpg_error_t
612 _ksba_cms_parse_signed_data_part_2 (ksba_cms_t cms)
613 {
614 struct tag_info ti;
615 gpg_error_t err;
616 struct signer_info_s *si, **si_tail;
617
618 /* read the next triplet which is either a [0], a [1] or a SET OF
619 (signerInfo) */
620 err = _ksba_ber_read_tl (cms->reader, &ti);
621 if (err)
622 return err;
623 if (ti.class == CLASS_UNIVERSAL && !ti.tag && !ti.is_constructed)
624 {
625 /* well, there might be still an end tag pending; eat it -
626 fixme: we should keep track of this to catch invalid
627 encodings */
628 err = _ksba_ber_read_tl (cms->reader, &ti);
629 if (err)
630 return err;
631 }
632
633 if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed)
634 { /* Implicit SET OF certificateSet with elements of CHOICE, but
635 we assume the first choice which is a Certificate; all other
636 choices are obsolete. We are now parsing a set of
637 certificates which we do by utilizing the ksba_cert code. */
638 ksba_cert_t cert;
639 int expect_endtag;
640
641 expect_endtag = !!ti.ndef;
642
643 for (;;)
644 {
645 struct certlist_s *cl;
646
647 /* First see whether this is really a sequence */
648 err = _ksba_ber_read_tl (cms->reader, &ti);
649 if (err)
650 return err;
651 if (expect_endtag && !ti.class && !ti.tag)
652 {
653 /* This is an end tag. Read the next tag but don't fail
654 if this is just an EOF. */
655 err = _ksba_ber_read_tl (cms->reader, &ti);
656 if (err)
657 {
658 if (gpg_err_code (err) == GPG_ERR_EOF)
659 err = 0;
660 return err;
661 }
662 break;
663 }
664 if (!(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
665 && ti.is_constructed))
666 break; /* not a sequence, so we are ready with the set */
667
668 /* We must unread so that the standard parser sees the sequence */
669 err = ksba_reader_unread (cms->reader, ti.buf, ti.nhdr);
670 if (err)
671 return err;
672 /* Use the standard certificate parser */
673 err = ksba_cert_new (&cert);
674 if (err)
675 return err;
676 err = ksba_cert_read_der (cert, cms->reader);
677 if (err)
678 {
679 ksba_cert_release (cert);
680 return err;
681 }
682 cl = xtrycalloc (1, sizeof *cl);
683 if (!cl)
684 {
685 ksba_cert_release (cert);
686 return gpg_error (GPG_ERR_ENOMEM);
687 }
688 cl->cert = cert;
689 cl->next = cms->cert_list;
690 cms->cert_list = cl;
691 }
692 }
693
694 if (ti.class == CLASS_CONTEXT && ti.tag == 1 && ti.is_constructed)
695 { /* implicit SET OF certificateList. We should delegate the
696 parsing to a - not yet existing - ksba_crl module. CRLs are
697 quite important for other applications too so we should
698 provide a nice interface */
699 int expect_endtag;
700
701
702 expect_endtag = !!ti.ndef;
703
704 /* FIXME this is just dummy read code */
705 /* fprintf (stderr,"WARNING: Can't handle CRLs yet\n"); */
706 for (;;)
707 {
708 /* first see whether this is really a sequence */
709 err = _ksba_ber_read_tl (cms->reader, &ti);
710 if (err)
711 return err;
712 if (expect_endtag && !ti.class && !ti.tag)
713 {
714 /* This is an end tag. Read the next tag but don't fail
715 if this is just an EOF. */
716 err = _ksba_ber_read_tl (cms->reader, &ti);
717 if (err)
718 {
719 if (gpg_err_code (err) == GPG_ERR_EOF)
720 err = 0;
721 return err;
722 }
723 break;
724 }
725 if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
726 && ti.is_constructed))
727 break; /* not a sequence, so we are ready with the set */
728
729 while (ti.length)
730 {
731 size_t n, nread;
732 char dummy[256];
733
734 n = ti.length > DIM(dummy) ? DIM(dummy): ti.length;
735 err = ksba_reader_read (cms->reader, dummy, n, &nread);
736 if (err)
737 return err;
738 ti.length -= nread;
739 }
740 }
741 }
742
743 /* expect a SET OF signerInfo */
744 if ( !(ti.class == CLASS_UNIVERSAL
745 && ti.tag == TYPE_SET && ti.is_constructed))
746 return gpg_error (GPG_ERR_INV_CMS_OBJ);
747
748 si_tail = &cms->signer_info;
749
750 while (ti.length)
751 {
752 size_t off1, off2;
753
754 off1 = ksba_reader_tell (cms->reader);
755 si = xtrycalloc (1, sizeof *si);
756 if (!si)
757 return gpg_error (GPG_ERR_ENOMEM);
758
759 err = create_and_run_decoder (cms->reader,
760 "CryptographicMessageSyntax.SignerInfo",
761 0,
762 &si->root, &si->image, &si->imagelen);
763 /* The signerInfo might be an empty set in the case of a certs-only
764 signature. Thus we have to allow for EOF here */
765 if (gpg_err_code (err) == GPG_ERR_EOF)
766 {
767 xfree (si);
768 err = 0;
769 break;
770 }
771 if (err)
772 {
773 xfree (si);
774 return err;
775 }
776
777 *si_tail = si;
778 si_tail = &si->next;
779
780 off2 = ksba_reader_tell (cms->reader);
781 if ( (off2 - off1) > ti.length )
782 ti.length = 0;
783 else
784 ti.length -= off2 - off1;
785 }
786
787 return 0;
788 }
789
790
791
792
793
794 /* Parse the structure:
795
796 EnvelopedData ::= SEQUENCE {
797 version INTEGER { v0(0), v1(1), v2(2), v3(3), v4(4) }),
798 originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
799 recipientInfos RecipientInfos,
800 encryptedContentInfo EncryptedContentInfo,
801 unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL }
802
803 OriginatorInfo ::= SEQUENCE {
804 certs [0] IMPLICIT CertificateSet OPTIONAL,
805 crls [1] IMPLICIT CertificateRevocationLists OPTIONAL }
806
807 RecipientInfos ::= SET OF RecipientInfo
808
809 EncryptedContentInfo ::= SEQUENCE {
810 contentType ContentType,
811 contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
812 encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
813
814 EncryptedContent ::= OCTET STRING
815
816 We stop parsing so that the next read will be the first byte of the
817 encryptedContent or (if there is no content) the unprotectedAttrs.
818 */
819 gpg_error_t
820 _ksba_cms_parse_enveloped_data_part_1 (ksba_cms_t cms)
821 {
822 struct tag_info ti;
823 gpg_error_t err;
824 int env_data_ndef;
825 unsigned long env_data_len;
826 int encr_cont_ndef = 0;
827 unsigned long encr_cont_len = 0;
828 int has_content = 0;
829 unsigned long off, len;
830 char *cont_oid = NULL;
831 char *algo_oid = NULL;
832 char *algo_parm = NULL;
833 size_t algo_parmlen = 0;
834 struct value_tree_s *vt, **vtend;
835
836 /* get the version */
837 err = parse_cms_version (cms->reader, &cms->cms_version,
838 &env_data_len, &env_data_ndef);
839 if (err)
840 return err;
841
842 /* read the next triplet which is either a [0] for originatorInfos
843 or a SET_OF (recipientInfo) */
844 err = _ksba_ber_read_tl (cms->reader, &ti);
845 if (err)
846 return err;
847
848 if (ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed)
849 { /* originatorInfo - but we skip it for now */
850 /* well, raise an error */
851 return gpg_error (GPG_ERR_UNSUPPORTED_CMS_OBJ);
852 }
853
854 /* Next one is the SET OF RecipientInfo:
855 * RecipientInfo ::= CHOICE {
856 * ktri KeyTransRecipientInfo,
857 * kari [1] KeyAgreeRecipientInfo,
858 * kekri [2] KEKRecipientInfo
859 * } */
860 if ( !(ti.class == CLASS_UNIVERSAL
861 && ti.tag == TYPE_SET && ti.is_constructed))
862 return gpg_error (GPG_ERR_INV_CMS_OBJ);
863
864
865 vtend = &cms->recp_info;
866 if (ti.ndef)
867 {
868 for (;;)
869 {
870 struct tag_info ti2;
871
872 err = _ksba_ber_read_tl (cms->reader, &ti2);
873 if (err)
874 return err;
875
876 if (!ti2.class && !ti2.tag)
877 break; /* End tag found: ready. */
878
879 /* Not an end tag: Push it back and run the decoder. */
880 err = ksba_reader_unread (cms->reader, ti2.buf, ti2.nhdr);
881 if (err)
882 return err;
883
884 vt = xtrycalloc (1, sizeof *vt);
885 if (!vt)
886 return gpg_error_from_syserror ();
887
888 err = create_and_run_decoder
889 (cms->reader,
890 "CryptographicMessageSyntax.RecipientInfo",
891 BER_DECODER_FLAG_FAST_STOP,
892 &vt->root, &vt->image, &vt->imagelen);
893 if (err)
894 {
895 xfree (vt);
896 return err;
897 }
898
899 *vtend = vt;
900 vtend = &vt->next;
901 }
902 }
903 else
904 {
905 while (ti.length)
906 {
907 size_t off1, off2;
908
909 off1 = ksba_reader_tell (cms->reader);
910 vt = xtrycalloc (1, sizeof *vt);
911 if (!vt)
912 return gpg_error_from_syserror ();
913
914 err = create_and_run_decoder
915 (cms->reader,
916 "CryptographicMessageSyntax.RecipientInfo",
917 BER_DECODER_FLAG_FAST_STOP,
918 &vt->root, &vt->image, &vt->imagelen);
919 if (err)
920 {
921 xfree (vt);
922 return err;
923 }
924
925 *vtend = vt;
926 vtend = &vt->next;
927
928 off2 = ksba_reader_tell (cms->reader);
929 if ( (off2 - off1) > ti.length )
930 ti.length = 0;
931 else
932 ti.length -= off2 - off1;
933 }
934 }
935
936 /* Now for the encryptedContentInfo */
937 off = ksba_reader_tell (cms->reader);
938 err = parse_encrypted_content_info (cms->reader,
939 &encr_cont_len, &encr_cont_ndef,
940 &cont_oid,
941 &algo_oid,
942 &algo_parm, &algo_parmlen,
943 &has_content);
944 if (err)
945 return err;
946 cms->inner_cont_len = encr_cont_len;
947 cms->inner_cont_ndef = encr_cont_ndef;
948 cms->inner_cont_oid = cont_oid;
949 cms->detached_data = !has_content;
950 cms->encr_algo_oid = algo_oid;
951 cms->encr_iv = algo_parm; algo_parm = NULL;
952 cms->encr_ivlen = algo_parmlen;
953 if (!env_data_ndef)
954 {
955 len = ksba_reader_tell (cms->reader) - off;
956 if (env_data_len < len)
957 return gpg_error (GPG_ERR_BAD_BER); /* parsed content info larger that sequence */
958 env_data_len -= len;
959 if (!encr_cont_ndef && env_data_len < encr_cont_len)
960 return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
961 }
962
963 return 0;
964 }
965
966
967 /* handle the unprotected attributes */
968 gpg_error_t
969 _ksba_cms_parse_enveloped_data_part_2 (ksba_cms_t cms)
970 {
971 (void)cms;
972 /* FIXME */
973 return 0;
974 }