Line data Source code
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 0 : read_byte (ksba_reader_t reader)
55 : {
56 : unsigned char buf;
57 : size_t nread;
58 : int rc;
59 :
60 : do
61 0 : rc = ksba_reader_read (reader, &buf, 1, &nread);
62 0 : while (!rc && !nread);
63 0 : return rc? -1: buf;
64 : }
65 :
66 : /* read COUNT bytes into buffer. Return 0 on success */
67 : static int
68 0 : read_buffer (ksba_reader_t reader, char *buffer, size_t count)
69 : {
70 : size_t nread;
71 :
72 0 : while (count)
73 : {
74 0 : if (ksba_reader_read (reader, buffer, count, &nread))
75 0 : return -1;
76 0 : buffer += nread;
77 0 : count -= nread;
78 : }
79 0 : return 0;
80 : }
81 :
82 : /* Create a new decoder and run it for the given element */
83 : static gpg_error_t
84 0 : 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 0 : err = ksba_asn_create_tree ("cms", &cms_tree);
94 0 : if (err)
95 0 : return err;
96 :
97 0 : decoder = _ksba_ber_decoder_new ();
98 0 : if (!decoder)
99 : {
100 0 : ksba_asn_tree_release (cms_tree);
101 0 : return gpg_error (GPG_ERR_ENOMEM);
102 : }
103 :
104 0 : err = _ksba_ber_decoder_set_reader (decoder, reader);
105 0 : if (err)
106 : {
107 0 : ksba_asn_tree_release (cms_tree);
108 0 : _ksba_ber_decoder_release (decoder);
109 0 : return err;
110 : }
111 :
112 0 : err = _ksba_ber_decoder_set_module (decoder, cms_tree);
113 0 : if (err)
114 : {
115 0 : ksba_asn_tree_release (cms_tree);
116 0 : _ksba_ber_decoder_release (decoder);
117 0 : return err;
118 : }
119 :
120 0 : err = _ksba_ber_decoder_decode (decoder, elem_name, flags,
121 : r_root, r_image, r_imagelen);
122 :
123 0 : _ksba_ber_decoder_release (decoder);
124 0 : ksba_asn_tree_release (cms_tree);
125 0 : 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 0 : 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 0 : char *oid = NULL;
155 :
156 : /* read the sequence triplet */
157 0 : err = _ksba_ber_read_tl (reader, &ti);
158 0 : if (err)
159 0 : return err;
160 0 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
161 0 : && ti.is_constructed) )
162 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
163 0 : content_len = ti.length;
164 0 : content_ndef = ti.ndef;
165 0 : if (!content_ndef && content_len < 3)
166 0 : return gpg_error (GPG_ERR_TOO_SHORT); /* to encode an OID */
167 :
168 : /* read the OID */
169 0 : err = _ksba_ber_read_tl (reader, &ti);
170 0 : if (err)
171 0 : return err;
172 0 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID
173 0 : && !ti.is_constructed && ti.length) )
174 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
175 0 : if (!content_ndef)
176 : {
177 0 : if (content_len < ti.nhdr)
178 0 : return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
179 0 : content_len -= ti.nhdr;
180 0 : if (content_len < ti.length)
181 0 : return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
182 0 : content_len -= ti.length;
183 : }
184 :
185 0 : if (ti.length >= DIM(oidbuf))
186 0 : return gpg_error (GPG_ERR_TOO_LARGE);
187 0 : err = read_buffer (reader, oidbuf, ti.length);
188 0 : if (err)
189 0 : return err;
190 0 : oid = ksba_oid_to_str (oidbuf, ti.length);
191 0 : if (!oid)
192 0 : return gpg_error (GPG_ERR_ENOMEM);
193 :
194 0 : if (!content_ndef && !content_len)
195 : { /* no data */
196 0 : *has_content = 0;
197 : }
198 : else
199 : { /* now read the explicit tag 0 which is optional */
200 0 : err = _ksba_ber_read_tl (reader, &ti);
201 0 : if (err)
202 : {
203 0 : xfree (oid);
204 0 : return err;
205 : }
206 :
207 0 : if ( ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed )
208 : {
209 0 : *has_content = 1;
210 : }
211 0 : else if ( ti.class == CLASS_UNIVERSAL && ti.tag == 0 && !ti.is_constructed )
212 : {
213 0 : *has_content = 0; /* this is optional - allow NUL tag */
214 : }
215 : else /* neither [0] nor NULL */
216 : {
217 0 : xfree (oid);
218 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
219 : }
220 0 : if (!content_ndef)
221 : {
222 0 : if (content_len < ti.nhdr)
223 0 : return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
224 0 : content_len -= ti.nhdr;
225 0 : if (!ti.ndef && content_len < ti.length)
226 0 : return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
227 : }
228 : }
229 0 : *r_len = content_len;
230 0 : *r_ndef = content_ndef;
231 0 : *r_oid = oid;
232 0 : 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 0 : 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 0 : char *cont_oid = NULL;
261 0 : char *algo_oid = NULL;
262 0 : 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 0 : err = _ksba_ber_read_tl (reader, &ti);
270 0 : if (err)
271 0 : return err;
272 0 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
273 0 : && ti.is_constructed) )
274 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
275 0 : content_len = ti.length;
276 0 : content_ndef = ti.ndef;
277 0 : if (!content_ndef && content_len < 3)
278 0 : return gpg_error (GPG_ERR_TOO_SHORT); /* to encode an OID */
279 :
280 : /* read the OID */
281 0 : err = _ksba_ber_read_tl (reader, &ti);
282 0 : if (err)
283 0 : return err;
284 0 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID
285 0 : && !ti.is_constructed && ti.length) )
286 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
287 0 : if (!content_ndef)
288 : {
289 0 : if (content_len < ti.nhdr)
290 0 : return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
291 0 : content_len -= ti.nhdr;
292 0 : if (content_len < ti.length)
293 0 : return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
294 0 : content_len -= ti.length;
295 : }
296 0 : if (ti.length >= DIM(tmpbuf))
297 0 : return gpg_error (GPG_ERR_TOO_LARGE);
298 0 : err = read_buffer (reader, tmpbuf, ti.length);
299 0 : if (err)
300 0 : return err;
301 0 : cont_oid = ksba_oid_to_str (tmpbuf, ti.length);
302 0 : if (!cont_oid)
303 0 : return gpg_error (GPG_ERR_ENOMEM);
304 :
305 : /* read the algorithmIdentifier */
306 0 : err = _ksba_ber_read_tl (reader, &ti);
307 0 : if (err)
308 0 : return err;
309 0 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
310 0 : && ti.is_constructed) )
311 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
312 0 : if (!content_ndef)
313 : {
314 0 : if (content_len < ti.nhdr)
315 0 : return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
316 0 : content_len -= ti.nhdr;
317 0 : if (content_len < ti.length)
318 0 : return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
319 0 : content_len -= ti.length;
320 : }
321 0 : if (ti.nhdr + ti.length >= DIM(tmpbuf))
322 0 : return gpg_error (GPG_ERR_TOO_LARGE);
323 0 : memcpy (tmpbuf, ti.buf, ti.nhdr);
324 0 : err = read_buffer (reader, tmpbuf+ti.nhdr, ti.length);
325 0 : if (err)
326 0 : return err;
327 0 : err = _ksba_parse_algorithm_identifier2 (tmpbuf, ti.nhdr+ti.length,
328 : &nread,&algo_oid,
329 : &algo_parm, &algo_parmlen);
330 0 : if (err)
331 0 : return err;
332 0 : assert (nread <= ti.nhdr + ti.length);
333 0 : if (nread < ti.nhdr + ti.length)
334 0 : return gpg_error (GPG_ERR_TOO_SHORT);
335 :
336 : /* the optional encryptedDataInfo */
337 0 : *has_content = 0;
338 0 : 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 0 : err = _ksba_ber_read_tl (reader, &ti);
343 0 : if (err)
344 : {
345 0 : xfree (cont_oid);
346 0 : xfree (algo_oid);
347 0 : 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 0 : if ( ti.class == CLASS_CONTEXT && ti.tag == 0 )
354 : {
355 0 : *has_content = 1;
356 0 : if (!content_ndef)
357 : {
358 0 : if (content_len < ti.nhdr)
359 0 : return gpg_error (GPG_ERR_BAD_BER);
360 0 : content_len -= ti.nhdr;
361 0 : if (!ti.ndef && content_len < ti.length)
362 0 : return gpg_error (GPG_ERR_BAD_BER);
363 : }
364 : }
365 : else /* not what we want - push it back */
366 : {
367 0 : *has_content = 0;
368 0 : err = ksba_reader_unread (reader, ti.buf, ti.nhdr);
369 0 : if (err)
370 0 : return err;
371 : }
372 : }
373 0 : *r_len = content_len;
374 0 : *r_ndef = content_ndef;
375 0 : *r_cont_oid = cont_oid;
376 0 : *r_algo_oid = algo_oid;
377 0 : *r_algo_parm = algo_parm;
378 0 : *r_algo_parmlen = algo_parmlen;
379 0 : 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 0 : _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 0 : err = parse_content_info (cms->reader, &content_len, &content_ndef,
406 : &oid, &has_content);
407 0 : 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 0 : if (gpg_err_code (err) == GPG_ERR_BAD_BER
413 0 : || gpg_err_code (err) == GPG_ERR_INV_CMS_OBJ
414 0 : || gpg_err_code (err) == GPG_ERR_TOO_SHORT)
415 0 : err = gpg_error (GPG_ERR_NO_CMS_OBJ);
416 0 : return err;
417 : }
418 0 : if (!has_content)
419 0 : return gpg_error (GPG_ERR_NO_CMS_OBJ); /* It is not optional here */
420 0 : cms->content.length = content_len;
421 0 : cms->content.ndef = content_ndef;
422 0 : xfree (cms->content.oid);
423 0 : cms->content.oid = oid;
424 0 : 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 0 : 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 0 : err = _ksba_ber_read_tl (reader, &ti);
443 0 : if (err)
444 0 : return err;
445 0 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
446 0 : && ti.is_constructed) )
447 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
448 0 : data_len = ti.length;
449 0 : data_ndef = ti.ndef;
450 0 : if (!data_ndef && data_len < 3)
451 0 : return gpg_error (GPG_ERR_TOO_SHORT); /*to encode the version*/
452 :
453 : /* read the version integer */
454 0 : err = _ksba_ber_read_tl (reader, &ti);
455 0 : if (err)
456 0 : return err;
457 0 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_INTEGER
458 0 : && !ti.is_constructed && ti.length) )
459 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
460 0 : if (!data_ndef)
461 : {
462 0 : if (data_len < ti.nhdr)
463 0 : return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
464 0 : data_len -= ti.nhdr;
465 0 : if (data_len < ti.length)
466 0 : return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
467 0 : data_len -= ti.length;
468 : }
469 0 : if (ti.length != 1)
470 0 : return gpg_error (GPG_ERR_UNSUPPORTED_CMS_VERSION);
471 0 : if ( (c=read_byte (reader)) == -1)
472 : {
473 0 : err = ksba_reader_error (reader);
474 0 : return err? err : gpg_error (GPG_ERR_GENERAL);
475 : }
476 0 : if ( !(c == 0 || c == 1 || c == 2 || c == 3 || c == 4) )
477 0 : return gpg_error (GPG_ERR_UNSUPPORTED_CMS_VERSION);
478 0 : *r_version = c;
479 0 : *r_len = data_len;
480 0 : *r_ndef = data_ndef;
481 0 : 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 0 : _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 0 : err = parse_cms_version (cms->reader, &cms->cms_version,
520 : &signed_data_len, &signed_data_ndef);
521 0 : if (err)
522 0 : return err;
523 :
524 : /* read the SET OF algorithmIdentifiers */
525 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
526 0 : if (err)
527 0 : return err;
528 0 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SET
529 0 : && ti.is_constructed) )
530 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ); /* not the expected SET tag */
531 0 : if (!signed_data_ndef)
532 : {
533 0 : if (signed_data_len < ti.nhdr)
534 0 : return gpg_error (GPG_ERR_BAD_BER); /* triplet header larger that sequence */
535 0 : signed_data_len -= ti.nhdr;
536 0 : if (!ti.ndef && signed_data_len < ti.length)
537 0 : return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
538 0 : signed_data_len -= ti.length;
539 : }
540 0 : algo_set_len = ti.length;
541 0 : algo_set_ndef = ti.ndef;
542 :
543 : /* fixme: we are not able to read ndef length algorithm indentifiers. */
544 0 : if (algo_set_ndef)
545 0 : return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
546 : /* read the entire sequence into a buffer (add one to avoid malloc(0)) */
547 0 : buffer = xtrymalloc (algo_set_len + 1);
548 0 : if (!buffer)
549 0 : return gpg_error (GPG_ERR_ENOMEM);
550 0 : if (read_buffer (cms->reader, buffer, algo_set_len))
551 : {
552 0 : xfree (buffer);
553 0 : err = ksba_reader_error (cms->reader);
554 0 : return err? err: gpg_error (GPG_ERR_GENERAL);
555 : }
556 0 : p = buffer;
557 0 : while (algo_set_len)
558 : {
559 : size_t nread;
560 : struct oidlist_s *ol;
561 :
562 0 : err = _ksba_parse_algorithm_identifier (p, algo_set_len, &nread, &oid);
563 0 : if (err)
564 : {
565 0 : xfree (buffer);
566 0 : return err;
567 : }
568 0 : assert (nread <= algo_set_len);
569 0 : algo_set_len -= nread;
570 0 : p += nread;
571 : /* store the oid */
572 0 : ol = xtrymalloc (sizeof *ol);
573 0 : if (!ol)
574 : {
575 0 : xfree (oid);
576 0 : return gpg_error (GPG_ERR_ENOMEM);
577 : }
578 0 : ol->oid = oid;
579 0 : ol->next = cms->digest_algos;
580 0 : cms->digest_algos = ol;
581 : }
582 0 : xfree (buffer); buffer = NULL;
583 :
584 : /* Now for the encapsulatedContentInfo */
585 0 : off = ksba_reader_tell (cms->reader);
586 0 : err = parse_content_info (cms->reader,
587 : &encap_cont_len, &encap_cont_ndef,
588 : &oid, &has_content);
589 0 : if (err)
590 0 : return err;
591 0 : cms->inner_cont_len = encap_cont_len;
592 0 : cms->inner_cont_ndef = encap_cont_ndef;
593 0 : cms->inner_cont_oid = oid;
594 0 : cms->detached_data = !has_content;
595 0 : if (!signed_data_ndef)
596 : {
597 0 : len = ksba_reader_tell (cms->reader) - off;
598 0 : if (signed_data_len < len)
599 0 : return gpg_error (GPG_ERR_BAD_BER); /* parsed content info larger that sequence */
600 0 : signed_data_len -= len;
601 0 : if (!encap_cont_ndef && signed_data_len < encap_cont_len)
602 0 : 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 0 : 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 0 : _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 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
621 0 : if (err)
622 0 : return err;
623 0 : 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 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
629 0 : if (err)
630 0 : return err;
631 : }
632 :
633 0 : 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 0 : expect_endtag = !!ti.ndef;
642 :
643 : for (;;)
644 0 : {
645 : struct certlist_s *cl;
646 :
647 : /* First see whether this is really a sequence */
648 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
649 0 : if (err)
650 0 : return err;
651 0 : if (expect_endtag && !ti.class && ti.tag == TYPE_NULL )
652 : {
653 : /* This is an end tag. Read the next tag but don't fail
654 : if this is just an EOF. */
655 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
656 0 : if (err)
657 : {
658 0 : if (gpg_err_code (err) == GPG_ERR_EOF)
659 0 : err = 0;
660 0 : return err;
661 : }
662 0 : break;
663 : }
664 0 : if (!(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
665 0 : && 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 0 : err = ksba_reader_unread (cms->reader, ti.buf, ti.nhdr);
670 0 : if (err)
671 0 : return err;
672 : /* Use the standard certificate parser */
673 0 : err = ksba_cert_new (&cert);
674 0 : if (err)
675 0 : return err;
676 0 : err = ksba_cert_read_der (cert, cms->reader);
677 0 : if (err)
678 : {
679 0 : ksba_cert_release (cert);
680 0 : return err;
681 : }
682 0 : cl = xtrycalloc (1, sizeof *cl);
683 0 : if (!cl)
684 : {
685 0 : ksba_cert_release (cert);
686 0 : return gpg_error (GPG_ERR_ENOMEM);
687 : }
688 0 : cl->cert = cert;
689 0 : cl->next = cms->cert_list;
690 0 : cms->cert_list = cl;
691 : }
692 : }
693 :
694 0 : 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 0 : 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 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
710 0 : if (err)
711 0 : return err;
712 0 : if (expect_endtag && !ti.class && ti.tag == TYPE_NULL )
713 : {
714 : /* This is an end tag. Read the next tag but don't fail
715 : if this is just an EOF. */
716 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
717 0 : if (err)
718 : {
719 0 : if (gpg_err_code (err) == GPG_ERR_EOF)
720 0 : err = 0;
721 0 : return err;
722 : }
723 0 : break;
724 : }
725 0 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
726 0 : && ti.is_constructed))
727 : break; /* not a sequence, so we are ready with the set */
728 :
729 0 : while (ti.length)
730 : {
731 : size_t n, nread;
732 : char dummy[256];
733 :
734 0 : n = ti.length > DIM(dummy) ? DIM(dummy): ti.length;
735 0 : err = ksba_reader_read (cms->reader, dummy, n, &nread);
736 0 : if (err)
737 0 : return err;
738 0 : ti.length -= nread;
739 : }
740 : }
741 : }
742 :
743 : /* expect a SET OF signerInfo */
744 0 : if ( !(ti.class == CLASS_UNIVERSAL
745 0 : && ti.tag == TYPE_SET && ti.is_constructed))
746 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
747 :
748 0 : si_tail = &cms->signer_info;
749 :
750 0 : while (ti.length)
751 : {
752 : size_t off1, off2;
753 :
754 0 : off1 = ksba_reader_tell (cms->reader);
755 0 : si = xtrycalloc (1, sizeof *si);
756 0 : if (!si)
757 0 : return gpg_error (GPG_ERR_ENOMEM);
758 :
759 0 : 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 0 : if (gpg_err_code (err) == GPG_ERR_EOF)
766 : {
767 0 : xfree (si);
768 0 : err = 0;
769 0 : break;
770 : }
771 0 : if (err)
772 : {
773 0 : xfree (si);
774 0 : return err;
775 : }
776 :
777 0 : *si_tail = si;
778 0 : si_tail = &si->next;
779 :
780 0 : off2 = ksba_reader_tell (cms->reader);
781 0 : if ( (off2 - off1) > ti.length )
782 0 : ti.length = 0;
783 : else
784 0 : ti.length -= off2 - off1;
785 : }
786 :
787 0 : 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 0 : _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;
827 : unsigned long encr_cont_len;
828 : int has_content;
829 : unsigned long off, len;
830 0 : char *cont_oid = NULL;
831 0 : char *algo_oid = NULL;
832 0 : char *algo_parm = NULL;
833 : size_t algo_parmlen;
834 : struct value_tree_s *vt, **vtend;
835 :
836 : /* get the version */
837 0 : err = parse_cms_version (cms->reader, &cms->cms_version,
838 : &env_data_len, &env_data_ndef);
839 0 : if (err)
840 0 : return err;
841 :
842 : /* read the next triplet which is either a [0] for originatorInfos
843 : or a SET_OF (recipientInfo) */
844 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
845 0 : if (err)
846 0 : return err;
847 :
848 0 : 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 0 : return gpg_error (GPG_ERR_UNSUPPORTED_CMS_OBJ);
852 : }
853 :
854 : /* Next one is the SET OF recipientInfos */
855 0 : if ( !(ti.class == CLASS_UNIVERSAL
856 0 : && ti.tag == TYPE_SET && ti.is_constructed))
857 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
858 :
859 0 : vtend = &cms->recp_info;
860 0 : if (ti.ndef)
861 : {
862 : for (;;)
863 0 : {
864 : struct tag_info ti2;
865 :
866 0 : err = _ksba_ber_read_tl (cms->reader, &ti2);
867 0 : if (err)
868 0 : return err;
869 :
870 0 : if (!ti2.class && !ti2.tag)
871 0 : break; /* End tag found: ready. */
872 :
873 : /* Not an end tag: Push it back and run the decoder. */
874 0 : err = ksba_reader_unread (cms->reader, ti2.buf, ti2.nhdr);
875 0 : if (err)
876 0 : return err;
877 :
878 0 : vt = xtrycalloc (1, sizeof *vt);
879 0 : if (!vt)
880 0 : return gpg_error_from_syserror ();
881 :
882 0 : err = create_and_run_decoder
883 : (cms->reader,
884 : "CryptographicMessageSyntax.KeyTransRecipientInfo",
885 : BER_DECODER_FLAG_FAST_STOP,
886 : &vt->root, &vt->image, &vt->imagelen);
887 0 : if (err)
888 : {
889 0 : xfree (vt);
890 0 : return err;
891 : }
892 :
893 0 : *vtend = vt;
894 0 : vtend = &vt->next;
895 : }
896 : }
897 : else
898 : {
899 0 : while (ti.length)
900 : {
901 : size_t off1, off2;
902 :
903 0 : off1 = ksba_reader_tell (cms->reader);
904 0 : vt = xtrycalloc (1, sizeof *vt);
905 0 : if (!vt)
906 0 : return gpg_error_from_syserror ();
907 :
908 0 : err = create_and_run_decoder
909 : (cms->reader,
910 : "CryptographicMessageSyntax.KeyTransRecipientInfo",
911 : 0,
912 : &vt->root, &vt->image, &vt->imagelen);
913 0 : if (err)
914 : {
915 0 : xfree (vt);
916 0 : return err;
917 : }
918 :
919 0 : *vtend = vt;
920 0 : vtend = &vt->next;
921 :
922 0 : off2 = ksba_reader_tell (cms->reader);
923 0 : if ( (off2 - off1) > ti.length )
924 0 : ti.length = 0;
925 : else
926 0 : ti.length -= off2 - off1;
927 : }
928 : }
929 :
930 : /* Now for the encryptedContentInfo */
931 0 : off = ksba_reader_tell (cms->reader);
932 0 : err = parse_encrypted_content_info (cms->reader,
933 : &encr_cont_len, &encr_cont_ndef,
934 : &cont_oid,
935 : &algo_oid,
936 : &algo_parm, &algo_parmlen,
937 : &has_content);
938 0 : if (err)
939 0 : return err;
940 0 : cms->inner_cont_len = encr_cont_len;
941 0 : cms->inner_cont_ndef = encr_cont_ndef;
942 0 : cms->inner_cont_oid = cont_oid;
943 0 : cms->detached_data = !has_content;
944 0 : cms->encr_algo_oid = algo_oid;
945 0 : cms->encr_iv = algo_parm; algo_parm = NULL;
946 0 : cms->encr_ivlen = algo_parmlen;
947 0 : if (!env_data_ndef)
948 : {
949 0 : len = ksba_reader_tell (cms->reader) - off;
950 0 : if (env_data_len < len)
951 0 : return gpg_error (GPG_ERR_BAD_BER); /* parsed content info larger that sequence */
952 0 : env_data_len -= len;
953 0 : if (!encr_cont_ndef && env_data_len < encr_cont_len)
954 0 : return gpg_error (GPG_ERR_BAD_BER); /* triplet larger that sequence */
955 : }
956 :
957 0 : return 0;
958 : }
959 :
960 :
961 : /* handle the unprotected attributes */
962 : gpg_error_t
963 0 : _ksba_cms_parse_enveloped_data_part_2 (ksba_cms_t cms)
964 : {
965 : (void)cms;
966 : /* FIXME */
967 0 : return 0;
968 : }
|