Line data Source code
1 : /* cms.c - cryptographic message syntax main functions
2 : * Copyright (C) 2001, 2003, 2004, 2008, 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 : #include <config.h>
32 : #include <stdio.h>
33 : #include <stdlib.h>
34 : #include <string.h>
35 : #include <assert.h>
36 : #include <errno.h>
37 :
38 : #include "util.h"
39 :
40 : #include "cms.h"
41 : #include "convert.h"
42 : #include "keyinfo.h"
43 : #include "der-encoder.h"
44 : #include "ber-help.h"
45 : #include "sexp-parse.h"
46 : #include "cert.h" /* need to access cert->root and cert->image */
47 :
48 : static gpg_error_t ct_parse_data (ksba_cms_t cms);
49 : static gpg_error_t ct_parse_signed_data (ksba_cms_t cms);
50 : static gpg_error_t ct_parse_enveloped_data (ksba_cms_t cms);
51 : static gpg_error_t ct_parse_digested_data (ksba_cms_t cms);
52 : static gpg_error_t ct_parse_encrypted_data (ksba_cms_t cms);
53 : static gpg_error_t ct_build_data (ksba_cms_t cms);
54 : static gpg_error_t ct_build_signed_data (ksba_cms_t cms);
55 : static gpg_error_t ct_build_enveloped_data (ksba_cms_t cms);
56 : static gpg_error_t ct_build_digested_data (ksba_cms_t cms);
57 : static gpg_error_t ct_build_encrypted_data (ksba_cms_t cms);
58 :
59 : static struct {
60 : const char *oid;
61 : ksba_content_type_t ct;
62 : gpg_error_t (*parse_handler)(ksba_cms_t);
63 : gpg_error_t (*build_handler)(ksba_cms_t);
64 : } content_handlers[] = {
65 : { "1.2.840.113549.1.7.1", KSBA_CT_DATA,
66 : ct_parse_data , ct_build_data },
67 : { "1.2.840.113549.1.7.2", KSBA_CT_SIGNED_DATA,
68 : ct_parse_signed_data , ct_build_signed_data },
69 : { "1.2.840.113549.1.7.3", KSBA_CT_ENVELOPED_DATA,
70 : ct_parse_enveloped_data, ct_build_enveloped_data },
71 : { "1.2.840.113549.1.7.5", KSBA_CT_DIGESTED_DATA,
72 : ct_parse_digested_data , ct_build_digested_data },
73 : { "1.2.840.113549.1.7.6", KSBA_CT_ENCRYPTED_DATA,
74 : ct_parse_encrypted_data, ct_build_encrypted_data },
75 : { "1.2.840.113549.1.9.16.1.2", KSBA_CT_AUTH_DATA },
76 : { NULL }
77 : };
78 :
79 : static const char oidstr_contentType[] = "1.2.840.113549.1.9.3";
80 : /*static char oid_contentType[9] = "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x03";*/
81 :
82 : static const char oidstr_messageDigest[] = "1.2.840.113549.1.9.4";
83 : static const char oid_messageDigest[9] ="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x04";
84 :
85 : static const char oidstr_signingTime[] = "1.2.840.113549.1.9.5";
86 : static const char oid_signingTime[9] = "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x05";
87 :
88 : static const char oidstr_smimeCapabilities[] = "1.2.840.113549.1.9.15";
89 :
90 :
91 :
92 : /* Helper for read_and_hash_cont(). */
93 : static gpg_error_t
94 0 : read_hash_block (ksba_cms_t cms, unsigned long nleft)
95 : {
96 : gpg_error_t err;
97 : char buffer[4096];
98 : size_t n, nread;
99 :
100 0 : while (nleft)
101 : {
102 0 : n = nleft < sizeof (buffer)? nleft : sizeof (buffer);
103 0 : err = ksba_reader_read (cms->reader, buffer, n, &nread);
104 0 : if (err)
105 0 : return err;
106 0 : nleft -= nread;
107 0 : if (cms->hash_fnc)
108 0 : cms->hash_fnc (cms->hash_fnc_arg, buffer, nread);
109 0 : if (cms->writer)
110 0 : err = ksba_writer_write (cms->writer, buffer, nread);
111 0 : if (err)
112 0 : return err;
113 : }
114 0 : return 0;
115 : }
116 :
117 :
118 : /* Copy all the bytes from the reader to the writer and hash them if a
119 : a hash function has been set. The writer may be NULL to just do
120 : the hashing */
121 : static gpg_error_t
122 0 : read_and_hash_cont (ksba_cms_t cms)
123 : {
124 0 : gpg_error_t err = 0;
125 : unsigned long nleft;
126 : struct tag_info ti;
127 :
128 0 : if (cms->inner_cont_ndef)
129 : {
130 : for (;;)
131 : {
132 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
133 0 : if (err)
134 0 : return err;
135 :
136 0 : if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OCTET_STRING
137 0 : && !ti.is_constructed)
138 : { /* next chunk */
139 0 : nleft = ti.length;
140 0 : err = read_hash_block (cms, nleft);
141 0 : if (err)
142 0 : return err;
143 : }
144 0 : else if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OCTET_STRING
145 0 : && ti.is_constructed)
146 : { /* next chunk is constructed */
147 : for (;;)
148 : {
149 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
150 0 : if (err)
151 0 : return err;
152 0 : if (ti.class == CLASS_UNIVERSAL
153 0 : && ti.tag == TYPE_OCTET_STRING
154 0 : && !ti.is_constructed)
155 : {
156 0 : nleft = ti.length;
157 0 : err = read_hash_block (cms, nleft);
158 0 : if (err)
159 0 : return err;
160 : }
161 0 : else if (ti.class == CLASS_UNIVERSAL && !ti.tag
162 0 : && !ti.is_constructed)
163 : break; /* ready with this chunk */
164 : else
165 0 : return gpg_error (GPG_ERR_ENCODING_PROBLEM);
166 : }
167 : }
168 0 : else if (ti.class == CLASS_UNIVERSAL && !ti.tag
169 0 : && !ti.is_constructed)
170 0 : return 0; /* ready */
171 : else
172 0 : return gpg_error (GPG_ERR_ENCODING_PROBLEM);
173 : }
174 : }
175 : else
176 : {
177 : /* This is basically the same as above but we allow for
178 : arbitrary types. Not sure whether it is really needed but
179 : right in the beginning of gnupg 1.9 we had at least one
180 : message with didn't used octet strings. Not ethat we don't
181 : do proper NLEFT checking but well why should we validate
182 : these things? Well, it might be nice to have such a feature
183 : but then we should write a more general mechanism to do
184 : that. */
185 0 : nleft = cms->inner_cont_len;
186 : /* First read the octet string but allow all types here */
187 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
188 0 : if (err)
189 0 : return err;
190 0 : if (nleft < ti.nhdr)
191 0 : return gpg_error (GPG_ERR_ENCODING_PROBLEM);
192 0 : nleft -= ti.nhdr;
193 :
194 0 : if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OCTET_STRING
195 0 : && ti.is_constructed)
196 : { /* Next chunk is constructed */
197 : for (;;)
198 : {
199 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
200 0 : if (err)
201 0 : return err;
202 0 : if (ti.class == CLASS_UNIVERSAL
203 0 : && ti.tag == TYPE_OCTET_STRING
204 0 : && !ti.is_constructed)
205 : {
206 0 : nleft = ti.length;
207 0 : err = read_hash_block (cms, nleft);
208 0 : if (err)
209 0 : return err;
210 : }
211 0 : else if (ti.class == CLASS_UNIVERSAL && !ti.tag
212 0 : && !ti.is_constructed)
213 : break; /* Ready with this chunk */
214 : else
215 0 : return gpg_error (GPG_ERR_ENCODING_PROBLEM);
216 : }
217 : }
218 0 : else if (ti.class == CLASS_UNIVERSAL && !ti.tag
219 0 : && !ti.is_constructed)
220 0 : return 0; /* ready */
221 : else
222 : {
223 0 : err = read_hash_block (cms, nleft);
224 0 : if (err)
225 0 : return err;
226 : }
227 : }
228 0 : return 0;
229 : }
230 :
231 :
232 :
233 : /* Copy all the encrypted bytes from the reader to the writer.
234 : Handles indefinite length encoding */
235 : static gpg_error_t
236 0 : read_encrypted_cont (ksba_cms_t cms)
237 : {
238 0 : gpg_error_t err = 0;
239 : unsigned long nleft;
240 : char buffer[4096];
241 : size_t n, nread;
242 :
243 0 : if (cms->inner_cont_ndef)
244 : {
245 : struct tag_info ti;
246 :
247 : /* fixme: this ist mostly a duplicate of the code in
248 : read_and_hash_cont(). */
249 : for (;;)
250 : {
251 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
252 0 : if (err)
253 0 : return err;
254 :
255 0 : if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OCTET_STRING
256 0 : && !ti.is_constructed)
257 : { /* next chunk */
258 0 : nleft = ti.length;
259 0 : while (nleft)
260 : {
261 0 : n = nleft < sizeof (buffer)? nleft : sizeof (buffer);
262 0 : err = ksba_reader_read (cms->reader, buffer, n, &nread);
263 0 : if (err)
264 0 : return err;
265 0 : nleft -= nread;
266 0 : err = ksba_writer_write (cms->writer, buffer, nread);
267 0 : if (err)
268 0 : return err;
269 : }
270 : }
271 0 : else if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OCTET_STRING
272 0 : && ti.is_constructed)
273 : { /* next chunk is constructed */
274 : for (;;)
275 : {
276 0 : err = _ksba_ber_read_tl (cms->reader, &ti);
277 0 : if (err)
278 0 : return err;
279 0 : if (ti.class == CLASS_UNIVERSAL
280 0 : && ti.tag == TYPE_OCTET_STRING
281 0 : && !ti.is_constructed)
282 : {
283 0 : nleft = ti.length;
284 0 : while (nleft)
285 : {
286 0 : n = nleft < sizeof (buffer)? nleft : sizeof (buffer);
287 0 : err = ksba_reader_read (cms->reader, buffer, n, &nread);
288 0 : if (err)
289 0 : return err;
290 0 : nleft -= nread;
291 0 : if (cms->writer)
292 0 : err = ksba_writer_write (cms->writer, buffer, nread);
293 0 : if (err)
294 0 : return err;
295 : }
296 : }
297 0 : else if (ti.class == CLASS_UNIVERSAL && !ti.tag
298 0 : && !ti.is_constructed)
299 : break; /* ready with this chunk */
300 : else
301 0 : return gpg_error (GPG_ERR_ENCODING_PROBLEM);
302 : }
303 : }
304 0 : else if (ti.class == CLASS_UNIVERSAL && !ti.tag
305 0 : && !ti.is_constructed)
306 0 : return 0; /* ready */
307 : else
308 0 : return gpg_error (GPG_ERR_ENCODING_PROBLEM);
309 : }
310 : }
311 : else
312 : {
313 0 : nleft = cms->inner_cont_len;
314 0 : while (nleft)
315 : {
316 0 : n = nleft < sizeof (buffer)? nleft : sizeof (buffer);
317 0 : err = ksba_reader_read (cms->reader, buffer, n, &nread);
318 0 : if (err)
319 0 : return err;
320 0 : nleft -= nread;
321 0 : err = ksba_writer_write (cms->writer, buffer, nread);
322 0 : if (err)
323 0 : return err;
324 : }
325 : }
326 0 : return 0;
327 : }
328 :
329 : /* copy data from reader to writer. Assume that it is an octet string
330 : and insert undefinite length headers where needed */
331 : static gpg_error_t
332 0 : write_encrypted_cont (ksba_cms_t cms)
333 : {
334 0 : gpg_error_t err = 0;
335 : char buffer[4096];
336 : size_t nread;
337 :
338 : /* we do it the simple way: the parts are made up from the chunks we
339 : got from the read function.
340 :
341 : Fixme: We should write the tag here, and write a definite length
342 : header if everything fits into our local buffer. Actually pretty
343 : simple to do, but I am too lazy right now. */
344 0 : while (!(err = ksba_reader_read (cms->reader, buffer,
345 : sizeof buffer, &nread)) )
346 : {
347 0 : err = _ksba_ber_write_tl (cms->writer, TYPE_OCTET_STRING,
348 : CLASS_UNIVERSAL, 0, nread);
349 0 : if (!err)
350 0 : err = ksba_writer_write (cms->writer, buffer, nread);
351 : }
352 0 : if (gpg_err_code (err) == GPG_ERR_EOF) /* write the end tag */
353 0 : err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
354 :
355 0 : return err;
356 : }
357 :
358 :
359 : /* Figure out whether the data read from READER is a CMS object and
360 : return its content type. This function does only peek at the
361 : READER and tries to identify the type with best effort. Because of
362 : the ubiquity of the stupid and insecure pkcs#12 format, the
363 : function will also identify those files and return KSBA_CT_PKCS12;
364 : there is and will be no other pkcs#12 support in this library. */
365 : ksba_content_type_t
366 0 : ksba_cms_identify (ksba_reader_t reader)
367 : {
368 : struct tag_info ti;
369 : unsigned char buffer[24];
370 : const unsigned char*p;
371 : size_t n, count;
372 : char *oid;
373 : int i;
374 0 : int maybe_p12 = 0;
375 :
376 0 : if (!reader)
377 0 : return KSBA_CT_NONE; /* oops */
378 :
379 : /* This is a common example of a CMS object - it is obvious that we
380 : only need to read a few bytes to get to the OID:
381 : 30 82 0B 59 06 09 2A 86 48 86 F7 0D 01 07 02 A0 82 0B 4A 30 82 0B 46 02
382 : ----------- ++++++++++++++++++++++++++++++++
383 : SEQUENCE OID (signedData)
384 : (2 byte len)
385 :
386 : For a pkcs12 message we have this:
387 :
388 : 30 82 08 59 02 01 03 30 82 08 1F 06 09 2A 86 48 86 F7 0D 01 07 01 A0 82
389 : ----------- ++++++++ ----------- ++++++++++++++++++++++++++++++++
390 : SEQUENCE INTEGER SEQUENCE OID (data)
391 :
392 : This we need to read at least 22 bytes, we add 2 bytes to cope with
393 : length headers store with 4 bytes.
394 : */
395 :
396 0 : for (count = sizeof buffer; count; count -= n)
397 : {
398 0 : if (ksba_reader_read (reader, buffer+sizeof (buffer)-count, count, &n))
399 0 : return KSBA_CT_NONE; /* too short */
400 : }
401 0 : n = sizeof buffer;
402 0 : if (ksba_reader_unread (reader, buffer, n))
403 0 : return KSBA_CT_NONE; /* oops */
404 :
405 0 : p = buffer;
406 0 : if (_ksba_ber_parse_tl (&p, &n, &ti))
407 0 : return KSBA_CT_NONE;
408 0 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
409 0 : && ti.is_constructed) )
410 0 : return KSBA_CT_NONE;
411 0 : if (_ksba_ber_parse_tl (&p, &n, &ti))
412 0 : return KSBA_CT_NONE;
413 0 : if ( ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_INTEGER
414 0 : && !ti.is_constructed && ti.length == 1 && n && *p == 3)
415 : {
416 0 : maybe_p12 = 1;
417 0 : p++;
418 0 : n--;
419 0 : if (_ksba_ber_parse_tl (&p, &n, &ti))
420 0 : return KSBA_CT_NONE;
421 0 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
422 0 : && ti.is_constructed) )
423 0 : return KSBA_CT_NONE;
424 0 : if (_ksba_ber_parse_tl (&p, &n, &ti))
425 0 : return KSBA_CT_NONE;
426 : }
427 0 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID
428 0 : && !ti.is_constructed && ti.length) || ti.length > n)
429 0 : return KSBA_CT_NONE;
430 0 : oid = ksba_oid_to_str (p, ti.length);
431 0 : if (!oid)
432 0 : return KSBA_CT_NONE; /* out of core */
433 0 : for (i=0; content_handlers[i].oid; i++)
434 : {
435 0 : if (!strcmp (content_handlers[i].oid, oid))
436 0 : break;
437 : }
438 0 : if (!content_handlers[i].oid)
439 0 : return KSBA_CT_NONE; /* unknown */
440 0 : if (maybe_p12 && (content_handlers[i].ct == KSBA_CT_DATA
441 0 : || content_handlers[i].ct == KSBA_CT_SIGNED_DATA))
442 0 : return KSBA_CT_PKCS12;
443 0 : return content_handlers[i].ct;
444 : }
445 :
446 :
447 :
448 : /**
449 : * ksba_cms_new:
450 : *
451 : * Create a new and empty CMS object
452 : *
453 : * Return value: A CMS object or an error code.
454 : **/
455 : gpg_error_t
456 0 : ksba_cms_new (ksba_cms_t *r_cms)
457 : {
458 0 : *r_cms = xtrycalloc (1, sizeof **r_cms);
459 0 : if (!*r_cms)
460 0 : return gpg_error_from_errno (errno);
461 0 : return 0;
462 : }
463 :
464 : /* Release a list of value trees. */
465 : static void
466 0 : release_value_tree (struct value_tree_s *tree)
467 : {
468 0 : while (tree)
469 : {
470 0 : struct value_tree_s *tmp = tree->next;
471 0 : _ksba_asn_release_nodes (tree->root);
472 0 : xfree (tree->image);
473 0 : xfree (tree);
474 0 : tree = tmp;
475 : }
476 0 : }
477 :
478 : /**
479 : * ksba_cms_release:
480 : * @cms: A CMS object
481 : *
482 : * Release a CMS object.
483 : **/
484 : void
485 0 : ksba_cms_release (ksba_cms_t cms)
486 : {
487 0 : if (!cms)
488 0 : return;
489 0 : xfree (cms->content.oid);
490 0 : while (cms->digest_algos)
491 : {
492 0 : struct oidlist_s *ol = cms->digest_algos->next;
493 0 : xfree (cms->digest_algos->oid);
494 0 : xfree (cms->digest_algos);
495 0 : cms->digest_algos = ol;
496 : }
497 0 : while (cms->cert_list)
498 : {
499 0 : struct certlist_s *cl = cms->cert_list->next;
500 0 : ksba_cert_release (cms->cert_list->cert);
501 0 : xfree (cms->cert_list->enc_val.algo);
502 0 : xfree (cms->cert_list->enc_val.value);
503 0 : xfree (cms->cert_list);
504 0 : cms->cert_list = cl;
505 : }
506 0 : while (cms->cert_info_list)
507 : {
508 0 : struct certlist_s *cl = cms->cert_info_list->next;
509 0 : ksba_cert_release (cms->cert_info_list->cert);
510 0 : xfree (cms->cert_info_list->enc_val.algo);
511 0 : xfree (cms->cert_info_list->enc_val.value);
512 0 : xfree (cms->cert_info_list);
513 0 : cms->cert_info_list = cl;
514 : }
515 0 : xfree (cms->inner_cont_oid);
516 0 : xfree (cms->encr_algo_oid);
517 0 : xfree (cms->encr_iv);
518 0 : xfree (cms->data.digest);
519 0 : while (cms->signer_info)
520 : {
521 0 : struct signer_info_s *tmp = cms->signer_info->next;
522 0 : _ksba_asn_release_nodes (cms->signer_info->root);
523 0 : xfree (cms->signer_info->image);
524 0 : xfree (cms->signer_info->cache.digest_algo);
525 0 : xfree (cms->signer_info);
526 0 : cms->signer_info = tmp;
527 : }
528 0 : release_value_tree (cms->recp_info);
529 0 : while (cms->sig_val)
530 : {
531 0 : struct sig_val_s *tmp = cms->sig_val->next;
532 0 : xfree (cms->sig_val->algo);
533 0 : xfree (cms->sig_val->value);
534 0 : xfree (cms->sig_val);
535 0 : cms->sig_val = tmp;
536 : }
537 0 : while (cms->capability_list)
538 : {
539 0 : struct oidparmlist_s *tmp = cms->capability_list->next;
540 0 : xfree (cms->capability_list->oid);
541 0 : xfree (cms->capability_list);
542 0 : cms->capability_list = tmp;
543 : }
544 :
545 0 : xfree (cms);
546 : }
547 :
548 :
549 : gpg_error_t
550 0 : ksba_cms_set_reader_writer (ksba_cms_t cms, ksba_reader_t r, ksba_writer_t w)
551 : {
552 0 : if (!cms || !(r || w))
553 0 : return gpg_error (GPG_ERR_INV_VALUE);
554 0 : if ((r && cms->reader) || (w && cms->writer) )
555 0 : return gpg_error (GPG_ERR_CONFLICT); /* already set */
556 :
557 0 : cms->reader = r;
558 0 : cms->writer = w;
559 0 : return 0;
560 : }
561 :
562 :
563 :
564 : gpg_error_t
565 0 : ksba_cms_parse (ksba_cms_t cms, ksba_stop_reason_t *r_stopreason)
566 : {
567 : gpg_error_t err;
568 : int i;
569 :
570 0 : if (!cms || !r_stopreason)
571 0 : return gpg_error (GPG_ERR_INV_VALUE);
572 :
573 0 : *r_stopreason = KSBA_SR_RUNNING;
574 0 : if (!cms->stop_reason)
575 : { /* Initial state: start parsing */
576 0 : err = _ksba_cms_parse_content_info (cms);
577 0 : if (err)
578 0 : return err;
579 0 : for (i=0; content_handlers[i].oid; i++)
580 : {
581 0 : if (!strcmp (content_handlers[i].oid, cms->content.oid))
582 0 : break;
583 : }
584 0 : if (!content_handlers[i].oid)
585 0 : return gpg_error (GPG_ERR_UNKNOWN_CMS_OBJ);
586 0 : if (!content_handlers[i].parse_handler)
587 0 : return gpg_error (GPG_ERR_UNSUPPORTED_CMS_OBJ);
588 0 : cms->content.ct = content_handlers[i].ct;
589 0 : cms->content.handler = content_handlers[i].parse_handler;
590 0 : cms->stop_reason = KSBA_SR_GOT_CONTENT;
591 : }
592 0 : else if (cms->content.handler)
593 : {
594 0 : err = cms->content.handler (cms);
595 0 : if (err)
596 0 : return err;
597 : }
598 : else
599 0 : return gpg_error (GPG_ERR_UNSUPPORTED_CMS_OBJ);
600 :
601 0 : *r_stopreason = cms->stop_reason;
602 0 : return 0;
603 : }
604 :
605 : gpg_error_t
606 0 : ksba_cms_build (ksba_cms_t cms, ksba_stop_reason_t *r_stopreason)
607 : {
608 : gpg_error_t err;
609 :
610 0 : if (!cms || !r_stopreason)
611 0 : return gpg_error (GPG_ERR_INV_VALUE);
612 :
613 0 : *r_stopreason = KSBA_SR_RUNNING;
614 0 : if (!cms->stop_reason)
615 : { /* Initial state: check that the content handler is known */
616 0 : if (!cms->writer)
617 0 : return gpg_error (GPG_ERR_MISSING_ACTION);
618 0 : if (!cms->content.handler)
619 0 : return gpg_error (GPG_ERR_MISSING_ACTION);
620 0 : if (!cms->inner_cont_oid)
621 0 : return gpg_error (GPG_ERR_MISSING_ACTION);
622 0 : cms->stop_reason = KSBA_SR_GOT_CONTENT;
623 : }
624 0 : else if (cms->content.handler)
625 : {
626 0 : err = cms->content.handler (cms);
627 0 : if (err)
628 0 : return err;
629 : }
630 : else
631 0 : return gpg_error (GPG_ERR_UNSUPPORTED_CMS_OBJ);
632 :
633 0 : *r_stopreason = cms->stop_reason;
634 0 : return 0;
635 : }
636 :
637 :
638 :
639 :
640 : /* Return the content type. A WHAT of 0 returns the real content type
641 : whereas a 1 returns the inner content type.
642 : */
643 : ksba_content_type_t
644 0 : ksba_cms_get_content_type (ksba_cms_t cms, int what)
645 : {
646 : int i;
647 :
648 0 : if (!cms)
649 0 : return 0;
650 0 : if (!what)
651 0 : return cms->content.ct;
652 :
653 0 : if (what == 1 && cms->inner_cont_oid)
654 : {
655 0 : for (i=0; content_handlers[i].oid; i++)
656 : {
657 0 : if (!strcmp (content_handlers[i].oid, cms->inner_cont_oid))
658 0 : return content_handlers[i].ct;
659 : }
660 : }
661 0 : return 0;
662 : }
663 :
664 :
665 : /* Return the object ID of the current cms. This is a constant string
666 : valid as long as the context is valid and no new parse is
667 : started. */
668 : const char *
669 0 : ksba_cms_get_content_oid (ksba_cms_t cms, int what)
670 : {
671 0 : if (!cms)
672 0 : return NULL;
673 0 : if (!what)
674 0 : return cms->content.oid;
675 0 : if (what == 1)
676 0 : return cms->inner_cont_oid;
677 0 : if (what == 2)
678 0 : return cms->encr_algo_oid;
679 0 : return NULL;
680 : }
681 :
682 :
683 : /* Copy the initialization vector into iv and its len into ivlen.
684 : The caller should provide a suitable large buffer */
685 : gpg_error_t
686 0 : ksba_cms_get_content_enc_iv (ksba_cms_t cms, void *iv,
687 : size_t maxivlen, size_t *ivlen)
688 : {
689 0 : if (!cms || !iv || !ivlen)
690 0 : return gpg_error (GPG_ERR_INV_VALUE);
691 0 : if (!cms->encr_ivlen)
692 0 : return gpg_error (GPG_ERR_NO_DATA);
693 0 : if (cms->encr_ivlen > maxivlen)
694 0 : return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);
695 0 : memcpy (iv, cms->encr_iv, cms->encr_ivlen);
696 0 : *ivlen = cms->encr_ivlen;
697 0 : return 0;
698 : }
699 :
700 :
701 : /**
702 : * ksba_cert_get_digest_algo_list:
703 : * @cert: Initialized certificate object
704 : * @idx: enumerator
705 : *
706 : * Figure out the the digest algorithm used for the signature and
707 : * return its OID. Note that the algos returned are just hints on
708 : * what to hash.
709 : *
710 : * Return value: NULL for no more algorithms or a string valid as long
711 : * as the the cms object is valid.
712 : **/
713 : const char *
714 0 : ksba_cms_get_digest_algo_list (ksba_cms_t cms, int idx)
715 : {
716 : struct oidlist_s *ol;
717 :
718 0 : if (!cms)
719 0 : return NULL;
720 :
721 0 : for (ol=cms->digest_algos; ol && idx; ol = ol->next, idx-- )
722 : ;
723 0 : if (!ol)
724 0 : return NULL;
725 0 : return ol->oid;
726 : }
727 :
728 :
729 : /**
730 : * ksba_cms_get_issuer_serial:
731 : * @cms: CMS object
732 : * @idx: index number
733 : * @r_issuer: returns the issuer
734 : * @r_serial: returns the serial number
735 : *
736 : * This functions returns the issuer and serial number either from the
737 : * sid or the rid elements of a CMS object.
738 : *
739 : * Return value: 0 on success or an error code. An error code of -1
740 : * is returned to indicate that there is no issuer with that idx,
741 : * GPG_ERR_No_Data is returned to indicate that there is no issuer at
742 : * all.
743 : **/
744 : gpg_error_t
745 0 : ksba_cms_get_issuer_serial (ksba_cms_t cms, int idx,
746 : char **r_issuer, ksba_sexp_t *r_serial)
747 : {
748 : gpg_error_t err;
749 : const char *issuer_path, *serial_path;
750 : AsnNode root;
751 : const unsigned char *image;
752 : AsnNode n;
753 :
754 0 : if (!cms)
755 0 : return gpg_error (GPG_ERR_INV_VALUE);
756 0 : if (idx < 0)
757 0 : return gpg_error (GPG_ERR_INV_INDEX);
758 :
759 0 : if (cms->signer_info)
760 : {
761 : struct signer_info_s *si;
762 :
763 0 : for (si=cms->signer_info; si && idx; si = si->next, idx-- )
764 : ;
765 0 : if (!si)
766 0 : return -1;
767 :
768 0 : issuer_path = "SignerInfo.sid.issuerAndSerialNumber.issuer";
769 0 : serial_path = "SignerInfo.sid.issuerAndSerialNumber.serialNumber";
770 0 : root = si->root;
771 0 : image = si->image;
772 : }
773 0 : else if (cms->recp_info)
774 : {
775 : struct value_tree_s *tmp;
776 :
777 0 : issuer_path = "KeyTransRecipientInfo.rid.issuerAndSerialNumber.issuer";
778 0 : serial_path = "KeyTransRecipientInfo.rid.issuerAndSerialNumber.serialNumber";
779 0 : for (tmp=cms->recp_info; tmp && idx; tmp=tmp->next, idx-- )
780 : ;
781 0 : if (!tmp)
782 0 : return -1;
783 0 : root = tmp->root;
784 0 : image = tmp->image;
785 : }
786 : else
787 0 : return gpg_error (GPG_ERR_NO_DATA);
788 :
789 0 : if (r_issuer)
790 : {
791 0 : n = _ksba_asn_find_node (root, issuer_path);
792 0 : if (!n || !n->down)
793 0 : return gpg_error (GPG_ERR_NO_VALUE);
794 0 : n = n->down; /* dereference the choice node */
795 :
796 0 : if (n->off == -1)
797 : {
798 : /* fputs ("get_issuer problem at node:\n", stderr); */
799 : /* _ksba_asn_node_dump_all (n, stderr); */
800 0 : return gpg_error (GPG_ERR_GENERAL);
801 : }
802 0 : err = _ksba_dn_to_str (image, n, r_issuer);
803 0 : if (err)
804 0 : return err;
805 : }
806 :
807 0 : if (r_serial)
808 : {
809 : char numbuf[22];
810 : int numbuflen;
811 : unsigned char *p;
812 :
813 : /* fixme: we do not release the r_issuer stuff on error */
814 0 : n = _ksba_asn_find_node (root, serial_path);
815 0 : if (!n)
816 0 : return gpg_error (GPG_ERR_NO_VALUE);
817 :
818 0 : if (n->off == -1)
819 : {
820 : /* fputs ("get_serial problem at node:\n", stderr); */
821 : /* _ksba_asn_node_dump_all (n, stderr); */
822 0 : return gpg_error (GPG_ERR_GENERAL);
823 : }
824 :
825 0 : sprintf (numbuf,"(%u:", (unsigned int)n->len);
826 0 : numbuflen = strlen (numbuf);
827 0 : p = xtrymalloc (numbuflen + n->len + 2);
828 0 : if (!p)
829 0 : return gpg_error (GPG_ERR_ENOMEM);
830 0 : strcpy (p, numbuf);
831 0 : memcpy (p+numbuflen, image + n->off + n->nhdr, n->len);
832 0 : p[numbuflen + n->len] = ')';
833 0 : p[numbuflen + n->len + 1] = 0;
834 0 : *r_serial = p;
835 : }
836 :
837 0 : return 0;
838 : }
839 :
840 :
841 :
842 : /**
843 : * ksba_cms_get_digest_algo:
844 : * @cms: CMS object
845 : * @idx: index of signer
846 : *
847 : * Figure out the the digest algorithm used by the signer @idx return
848 : * its OID. This is the algorithm acually used to calculate the
849 : * signature.
850 : *
851 : * Return value: NULL for no such signer or a constn string valid as
852 : * long as the CMS object lives.
853 : **/
854 : const char *
855 0 : ksba_cms_get_digest_algo (ksba_cms_t cms, int idx)
856 : {
857 : AsnNode n;
858 : char *algo;
859 : struct signer_info_s *si;
860 :
861 0 : if (!cms)
862 0 : return NULL;
863 0 : if (!cms->signer_info)
864 0 : return NULL;
865 0 : if (idx < 0)
866 0 : return NULL;
867 :
868 0 : for (si=cms->signer_info; si && idx; si = si->next, idx-- )
869 : ;
870 0 : if (!si)
871 0 : return NULL;
872 :
873 0 : if (si->cache.digest_algo)
874 0 : return si->cache.digest_algo;
875 :
876 0 : n = _ksba_asn_find_node (si->root, "SignerInfo.digestAlgorithm.algorithm");
877 0 : algo = _ksba_oid_node_to_str (si->image, n);
878 0 : if (algo)
879 : {
880 0 : si->cache.digest_algo = algo;
881 : }
882 0 : return algo;
883 : }
884 :
885 :
886 : /**
887 : * ksba_cms_get_cert:
888 : * @cms: CMS object
889 : * @idx: enumerator
890 : *
891 : * Get the certificate out of a CMS. The caller should use this in a
892 : * loop to get all certificates. The returned certificate is a
893 : * shallow copy of the original one; the caller must still use
894 : * ksba_cert_release() to free it.
895 : *
896 : * Return value: A Certificate object or NULL for end of list or error
897 : **/
898 : ksba_cert_t
899 0 : ksba_cms_get_cert (ksba_cms_t cms, int idx)
900 : {
901 : struct certlist_s *cl;
902 :
903 0 : if (!cms || idx < 0)
904 0 : return NULL;
905 :
906 0 : for (cl=cms->cert_list; cl && idx; cl = cl->next, idx--)
907 : ;
908 0 : if (!cl)
909 0 : return NULL;
910 0 : ksba_cert_ref (cl->cert);
911 0 : return cl->cert;
912 : }
913 :
914 :
915 : /*
916 : Return the extension attribute messageDigest
917 : */
918 : gpg_error_t
919 0 : ksba_cms_get_message_digest (ksba_cms_t cms, int idx,
920 : char **r_digest, size_t *r_digest_len)
921 : {
922 : AsnNode nsiginfo, n;
923 : struct signer_info_s *si;
924 :
925 0 : if (!cms || !r_digest || !r_digest_len)
926 0 : return gpg_error (GPG_ERR_INV_VALUE);
927 0 : if (!cms->signer_info)
928 0 : return gpg_error (GPG_ERR_NO_DATA);
929 0 : if (idx < 0)
930 0 : return gpg_error (GPG_ERR_INV_INDEX);
931 :
932 0 : for (si=cms->signer_info; si && idx; si = si->next, idx-- )
933 : ;
934 0 : if (!si)
935 0 : return -1;
936 :
937 :
938 0 : *r_digest = NULL;
939 0 : *r_digest_len = 0;
940 0 : nsiginfo = _ksba_asn_find_node (si->root, "SignerInfo.signedAttrs");
941 0 : if (!nsiginfo)
942 0 : return gpg_error (GPG_ERR_BUG);
943 :
944 0 : n = _ksba_asn_find_type_value (si->image, nsiginfo, 0,
945 : oid_messageDigest, DIM(oid_messageDigest));
946 0 : if (!n)
947 0 : return 0; /* this is okay, because the element is optional */
948 :
949 : /* check that there is only one */
950 0 : if (_ksba_asn_find_type_value (si->image, nsiginfo, 1,
951 : oid_messageDigest, DIM(oid_messageDigest)))
952 0 : return gpg_error (GPG_ERR_DUP_VALUE);
953 :
954 : /* the value is is a SET OF OCTECT STRING but the set must have
955 : excactly one OCTECT STRING. (rfc2630 11.2) */
956 0 : if ( !(n->type == TYPE_SET_OF && n->down
957 0 : && n->down->type == TYPE_OCTET_STRING && !n->down->right))
958 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
959 0 : n = n->down;
960 0 : if (n->off == -1)
961 0 : return gpg_error (GPG_ERR_BUG);
962 :
963 0 : *r_digest_len = n->len;
964 0 : *r_digest = xtrymalloc (n->len);
965 0 : if (!*r_digest)
966 0 : return gpg_error (GPG_ERR_ENOMEM);
967 0 : memcpy (*r_digest, si->image + n->off + n->nhdr, n->len);
968 0 : return 0;
969 : }
970 :
971 :
972 : /* Return the extension attribute signing time, which may be empty for no
973 : signing time available. */
974 : gpg_error_t
975 0 : ksba_cms_get_signing_time (ksba_cms_t cms, int idx, ksba_isotime_t r_sigtime)
976 : {
977 : AsnNode nsiginfo, n;
978 : struct signer_info_s *si;
979 :
980 0 : if (!cms)
981 0 : return gpg_error (GPG_ERR_INV_VALUE);
982 0 : *r_sigtime = 0;
983 0 : if (!cms->signer_info)
984 0 : return gpg_error (GPG_ERR_NO_DATA);
985 0 : if (idx < 0)
986 0 : return gpg_error (GPG_ERR_INV_INDEX);
987 :
988 0 : for (si=cms->signer_info; si && idx; si = si->next, idx-- )
989 : ;
990 0 : if (!si)
991 0 : return -1;
992 :
993 0 : *r_sigtime = 0;
994 0 : nsiginfo = _ksba_asn_find_node (si->root, "SignerInfo.signedAttrs");
995 0 : if (!nsiginfo)
996 0 : return 0; /* This is okay because signedAttribs are optional. */
997 :
998 0 : n = _ksba_asn_find_type_value (si->image, nsiginfo, 0,
999 : oid_signingTime, DIM(oid_signingTime));
1000 0 : if (!n)
1001 0 : return 0; /* This is okay because signing time is optional. */
1002 :
1003 : /* check that there is only one */
1004 0 : if (_ksba_asn_find_type_value (si->image, nsiginfo, 1,
1005 : oid_signingTime, DIM(oid_signingTime)))
1006 0 : return gpg_error (GPG_ERR_DUP_VALUE);
1007 :
1008 : /* the value is is a SET OF CHOICE but the set must have
1009 : excactly one CHOICE of generalized or utctime. (rfc2630 11.3) */
1010 0 : if ( !(n->type == TYPE_SET_OF && n->down
1011 0 : && (n->down->type == TYPE_GENERALIZED_TIME
1012 0 : || n->down->type == TYPE_UTC_TIME)
1013 0 : && !n->down->right))
1014 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
1015 0 : n = n->down;
1016 0 : if (n->off == -1)
1017 0 : return gpg_error (GPG_ERR_BUG);
1018 :
1019 0 : return _ksba_asntime_to_iso (si->image + n->off + n->nhdr, n->len,
1020 0 : n->type == TYPE_UTC_TIME, r_sigtime);
1021 : }
1022 :
1023 :
1024 : /* Return a list of OIDs stored as signed attributes for the signature
1025 : number IDX. All the values (OIDs) for the the requested OID REQOID
1026 : are returned delimited by a linefeed. Caller must free that
1027 : list. -1 is returned when IDX is larger than the number of
1028 : signatures, GPG_ERR_No_Data is returned when there is no such
1029 : attribute for the given signer. */
1030 : gpg_error_t
1031 0 : ksba_cms_get_sigattr_oids (ksba_cms_t cms, int idx,
1032 : const char *reqoid, char **r_value)
1033 : {
1034 : gpg_error_t err;
1035 : AsnNode nsiginfo, n;
1036 : struct signer_info_s *si;
1037 : unsigned char *reqoidbuf;
1038 : size_t reqoidlen;
1039 0 : char *retstr = NULL;
1040 : int i;
1041 :
1042 0 : if (!cms || !r_value)
1043 0 : return gpg_error (GPG_ERR_INV_VALUE);
1044 0 : if (!cms->signer_info)
1045 0 : return gpg_error (GPG_ERR_NO_DATA);
1046 0 : if (idx < 0)
1047 0 : return gpg_error (GPG_ERR_INV_INDEX);
1048 0 : *r_value = NULL;
1049 :
1050 0 : for (si=cms->signer_info; si && idx; si = si->next, idx-- )
1051 : ;
1052 0 : if (!si)
1053 0 : return -1; /* no more signers */
1054 :
1055 0 : nsiginfo = _ksba_asn_find_node (si->root, "SignerInfo.signedAttrs");
1056 0 : if (!nsiginfo)
1057 0 : return -1; /* this is okay, because signedAttribs are optional */
1058 :
1059 0 : err = ksba_oid_from_str (reqoid, &reqoidbuf, &reqoidlen);
1060 0 : if(err)
1061 0 : return err;
1062 :
1063 0 : for (i=0; (n = _ksba_asn_find_type_value (si->image, nsiginfo,
1064 0 : i, reqoidbuf, reqoidlen)); i++)
1065 : {
1066 : char *line, *p;
1067 :
1068 : /* the value is is a SET OF OBJECT ID but the set must have
1069 : excactly one OBJECT ID. (rfc2630 11.1) */
1070 0 : if ( !(n->type == TYPE_SET_OF && n->down
1071 0 : && n->down->type == TYPE_OBJECT_ID && !n->down->right))
1072 : {
1073 0 : xfree (reqoidbuf);
1074 0 : xfree (retstr);
1075 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
1076 : }
1077 0 : n = n->down;
1078 0 : if (n->off == -1)
1079 : {
1080 0 : xfree (reqoidbuf);
1081 0 : xfree (retstr);
1082 0 : return gpg_error (GPG_ERR_BUG);
1083 : }
1084 :
1085 0 : p = _ksba_oid_node_to_str (si->image, n);
1086 0 : if (!p)
1087 : {
1088 0 : xfree (reqoidbuf);
1089 0 : xfree (retstr);
1090 0 : return gpg_error (GPG_ERR_INV_CMS_OBJ);
1091 : }
1092 :
1093 0 : if (!retstr)
1094 0 : line = retstr = xtrymalloc (strlen (p) + 2);
1095 : else
1096 : {
1097 0 : char *tmp = xtryrealloc (retstr,
1098 : strlen (retstr) + 1 + strlen (p) + 2);
1099 0 : if (!tmp)
1100 0 : line = NULL;
1101 : else
1102 : {
1103 0 : retstr = tmp;
1104 0 : line = stpcpy (retstr + strlen (retstr), "\n");
1105 : }
1106 : }
1107 0 : if (!line)
1108 : {
1109 0 : xfree (reqoidbuf);
1110 0 : xfree (retstr);
1111 0 : xfree (p);
1112 0 : return gpg_error (GPG_ERR_ENOMEM);
1113 : }
1114 0 : strcpy (line, p);
1115 0 : xfree (p);
1116 : }
1117 0 : xfree (reqoidbuf);
1118 0 : if (!n && !i)
1119 0 : return -1; /* no such attribute */
1120 0 : *r_value = retstr;
1121 0 : return 0;
1122 : }
1123 :
1124 :
1125 : /**
1126 : * ksba_cms_get_sig_val:
1127 : * @cms: CMS object
1128 : * @idx: index of signer
1129 : *
1130 : * Return the actual signature of signer @idx in a format suitable to
1131 : * be used as input to Libgcrypt's verification function. The caller
1132 : * must free the returned string.
1133 : *
1134 : * Return value: NULL or a string with a S-Exp.
1135 : **/
1136 : ksba_sexp_t
1137 0 : ksba_cms_get_sig_val (ksba_cms_t cms, int idx)
1138 : {
1139 : AsnNode n, n2;
1140 : gpg_error_t err;
1141 : ksba_sexp_t string;
1142 : struct signer_info_s *si;
1143 :
1144 0 : if (!cms)
1145 0 : return NULL;
1146 0 : if (!cms->signer_info)
1147 0 : return NULL;
1148 0 : if (idx < 0)
1149 0 : return NULL;
1150 :
1151 0 : for (si=cms->signer_info; si && idx; si = si->next, idx-- )
1152 : ;
1153 0 : if (!si)
1154 0 : return NULL;
1155 :
1156 0 : n = _ksba_asn_find_node (si->root, "SignerInfo.signatureAlgorithm");
1157 0 : if (!n)
1158 0 : return NULL;
1159 0 : if (n->off == -1)
1160 : {
1161 : /* fputs ("ksba_cms_get_sig_val problem at node:\n", stderr); */
1162 : /* _ksba_asn_node_dump_all (n, stderr); */
1163 0 : return NULL;
1164 : }
1165 :
1166 0 : n2 = n->right; /* point to the actual value */
1167 0 : err = _ksba_sigval_to_sexp (si->image + n->off,
1168 0 : n->nhdr + n->len
1169 0 : + ((!n2||n2->off == -1)? 0:(n2->nhdr+n2->len)),
1170 : &string);
1171 0 : if (err)
1172 0 : return NULL;
1173 :
1174 0 : return string;
1175 : }
1176 :
1177 :
1178 : /**
1179 : * ksba_cms_get_enc_val:
1180 : * @cms: CMS object
1181 : * @idx: index of recipient info
1182 : *
1183 : * Return the encrypted value (the session key) of recipient @idx in a
1184 : * format suitable to be used as input to Libgcrypt's decryption
1185 : * function. The caller must free the returned string.
1186 : *
1187 : * Return value: NULL or a string with a S-Exp.
1188 : **/
1189 : ksba_sexp_t
1190 0 : ksba_cms_get_enc_val (ksba_cms_t cms, int idx)
1191 : {
1192 : AsnNode n, n2;
1193 : gpg_error_t err;
1194 : ksba_sexp_t string;
1195 : struct value_tree_s *vt;
1196 :
1197 0 : if (!cms)
1198 0 : return NULL;
1199 0 : if (!cms->recp_info)
1200 0 : return NULL;
1201 0 : if (idx < 0)
1202 0 : return NULL;
1203 :
1204 0 : for (vt=cms->recp_info; vt && idx; vt=vt->next, idx--)
1205 : ;
1206 0 : if (!vt)
1207 0 : return NULL; /* No value at this IDX */
1208 :
1209 :
1210 0 : n = _ksba_asn_find_node (vt->root,
1211 : "KeyTransRecipientInfo.keyEncryptionAlgorithm");
1212 0 : if (!n)
1213 0 : return NULL;
1214 0 : if (n->off == -1)
1215 : {
1216 : /* fputs ("ksba_cms_get_enc_val problem at node:\n", stderr); */
1217 : /* _ksba_asn_node_dump_all (n, stderr); */
1218 0 : return NULL;
1219 : }
1220 :
1221 0 : n2 = n->right; /* point to the actual value */
1222 0 : err = _ksba_encval_to_sexp (vt->image + n->off,
1223 0 : n->nhdr + n->len
1224 0 : + ((!n2||n2->off == -1)? 0:(n2->nhdr+n2->len)),
1225 : &string);
1226 0 : if (err)
1227 0 : return NULL;
1228 :
1229 0 : return string;
1230 : }
1231 :
1232 :
1233 :
1234 :
1235 :
1236 : /* Provide a hash function so that we are able to hash the data */
1237 : void
1238 0 : ksba_cms_set_hash_function (ksba_cms_t cms,
1239 : void (*hash_fnc)(void *, const void *, size_t),
1240 : void *hash_fnc_arg)
1241 : {
1242 0 : if (cms)
1243 : {
1244 0 : cms->hash_fnc = hash_fnc;
1245 0 : cms->hash_fnc_arg = hash_fnc_arg;
1246 : }
1247 0 : }
1248 :
1249 :
1250 : /* hash the signed attributes of the given signer */
1251 : gpg_error_t
1252 0 : ksba_cms_hash_signed_attrs (ksba_cms_t cms, int idx)
1253 : {
1254 : AsnNode n;
1255 : struct signer_info_s *si;
1256 :
1257 0 : if (!cms)
1258 0 : return gpg_error (GPG_ERR_INV_VALUE);
1259 0 : if (!cms->hash_fnc)
1260 0 : return gpg_error (GPG_ERR_MISSING_ACTION);
1261 0 : if (idx < 0)
1262 0 : return -1;
1263 :
1264 0 : for (si=cms->signer_info; si && idx; si = si->next, idx-- )
1265 : ;
1266 0 : if (!si)
1267 0 : return -1;
1268 :
1269 0 : n = _ksba_asn_find_node (si->root, "SignerInfo.signedAttrs");
1270 0 : if (!n || n->off == -1)
1271 0 : return gpg_error (GPG_ERR_NO_VALUE);
1272 :
1273 : /* We don't hash the implicit tag [0] but a SET tag */
1274 0 : cms->hash_fnc (cms->hash_fnc_arg, "\x31", 1);
1275 0 : cms->hash_fnc (cms->hash_fnc_arg,
1276 0 : si->image + n->off + 1, n->nhdr + n->len - 1);
1277 :
1278 0 : return 0;
1279 : }
1280 :
1281 :
1282 : /*
1283 : Code to create CMS structures
1284 : */
1285 :
1286 :
1287 : /**
1288 : * ksba_cms_set_content_type:
1289 : * @cms: A CMS object
1290 : * @what: 0 for content type, 1 for inner content type
1291 : * @type: Tyep constant
1292 : *
1293 : * Set the content type used for build operations. This should be the
1294 : * first operation before starting to create a CMS message.
1295 : *
1296 : * Return value: 0 on success or an error code
1297 : **/
1298 : gpg_error_t
1299 0 : ksba_cms_set_content_type (ksba_cms_t cms, int what, ksba_content_type_t type)
1300 : {
1301 : int i;
1302 : char *oid;
1303 :
1304 0 : if (!cms || what < 0 || what > 1 )
1305 0 : return gpg_error (GPG_ERR_INV_VALUE);
1306 :
1307 0 : for (i=0; content_handlers[i].oid; i++)
1308 : {
1309 0 : if (content_handlers[i].ct == type)
1310 0 : break;
1311 : }
1312 0 : if (!content_handlers[i].oid)
1313 0 : return gpg_error (GPG_ERR_UNKNOWN_CMS_OBJ);
1314 0 : if (!content_handlers[i].build_handler)
1315 0 : return gpg_error (GPG_ERR_UNSUPPORTED_CMS_OBJ);
1316 0 : oid = xtrystrdup (content_handlers[i].oid);
1317 0 : if (!oid)
1318 0 : return gpg_error (GPG_ERR_ENOMEM);
1319 :
1320 0 : if (!what)
1321 : {
1322 0 : cms->content.oid = oid;
1323 0 : cms->content.ct = content_handlers[i].ct;
1324 0 : cms->content.handler = content_handlers[i].build_handler;
1325 : }
1326 : else
1327 : {
1328 0 : cms->inner_cont_oid = oid;
1329 : }
1330 :
1331 0 : return 0;
1332 : }
1333 :
1334 :
1335 : /**
1336 : * ksba_cms_add_digest_algo:
1337 : * @cms: A CMS object
1338 : * @oid: A stringified object OID describing the hash algorithm
1339 : *
1340 : * Set the algorithm to be used for creating the hash. Note, that we
1341 : * currently can't do a per-signer hash.
1342 : *
1343 : * Return value: 0 on success or an error code
1344 : **/
1345 : gpg_error_t
1346 0 : ksba_cms_add_digest_algo (ksba_cms_t cms, const char *oid)
1347 : {
1348 : struct oidlist_s *ol;
1349 :
1350 0 : if (!cms || !oid)
1351 0 : return gpg_error (GPG_ERR_INV_VALUE);
1352 :
1353 0 : ol = xtrymalloc (sizeof *ol);
1354 0 : if (!ol)
1355 0 : return gpg_error (GPG_ERR_ENOMEM);
1356 :
1357 0 : ol->oid = xtrystrdup (oid);
1358 0 : if (!ol->oid)
1359 : {
1360 0 : xfree (ol);
1361 0 : return gpg_error (GPG_ERR_ENOMEM);
1362 : }
1363 0 : ol->next = cms->digest_algos;
1364 0 : cms->digest_algos = ol;
1365 0 : return 0;
1366 : }
1367 :
1368 :
1369 : /**
1370 : * ksba_cms_add_signer:
1371 : * @cms: A CMS object
1372 : * @cert: A certificate used to describe the signer.
1373 : *
1374 : * This functions starts assembly of a new signed data content or adds
1375 : * another signer to the list of signers.
1376 : *
1377 : * Return value: 0 on success or an error code.
1378 : **/
1379 : gpg_error_t
1380 0 : ksba_cms_add_signer (ksba_cms_t cms, ksba_cert_t cert)
1381 : {
1382 : struct certlist_s *cl, *cl2;
1383 :
1384 0 : if (!cms)
1385 0 : return gpg_error (GPG_ERR_INV_VALUE);
1386 :
1387 0 : cl = xtrycalloc (1,sizeof *cl);
1388 0 : if (!cl)
1389 0 : return gpg_error (GPG_ERR_ENOMEM);
1390 :
1391 0 : ksba_cert_ref (cert);
1392 0 : cl->cert = cert;
1393 0 : if (!cms->cert_list)
1394 0 : cms->cert_list = cl;
1395 : else
1396 : {
1397 0 : for (cl2=cms->cert_list; cl2->next; cl2 = cl2->next)
1398 : ;
1399 0 : cl2->next = cl;
1400 : }
1401 0 : return 0;
1402 : }
1403 :
1404 : /**
1405 : * ksba_cms_add_cert:
1406 : * @cms: A CMS object
1407 : * @cert: A certificate to be send along with the signed data.
1408 : *
1409 : * This functions adds a certificate to the list of certificates send
1410 : * along with the signed data. Using this is optional but it is very
1411 : * common to include at least the certificate of the signer it self.
1412 : *
1413 : * Return value: 0 on success or an error code.
1414 : **/
1415 : gpg_error_t
1416 0 : ksba_cms_add_cert (ksba_cms_t cms, ksba_cert_t cert)
1417 : {
1418 : struct certlist_s *cl;
1419 :
1420 0 : if (!cms || !cert)
1421 0 : return gpg_error (GPG_ERR_INV_VALUE);
1422 :
1423 : /* first check whether this is a duplicate. */
1424 0 : for (cl = cms->cert_info_list; cl; cl = cl->next)
1425 : {
1426 0 : if (!_ksba_cert_cmp (cert, cl->cert))
1427 0 : return 0; /* duplicate */
1428 : }
1429 :
1430 : /* Okay, add it. */
1431 0 : cl = xtrycalloc (1,sizeof *cl);
1432 0 : if (!cl)
1433 0 : return gpg_error (GPG_ERR_ENOMEM);
1434 :
1435 0 : ksba_cert_ref (cert);
1436 0 : cl->cert = cert;
1437 0 : cl->next = cms->cert_info_list;
1438 0 : cms->cert_info_list = cl;
1439 0 : return 0;
1440 : }
1441 :
1442 :
1443 : /* Add an S/MIME capability as an extended attribute to the message.
1444 : This function is to be called for each capability in turn. The
1445 : first capability added will receive the highest priority. CMS is
1446 : the context, OID the object identifier of the capability and if DER
1447 : is not NULL it is used as the DER-encoded parameters of the
1448 : capability; the length of that DER object is given in DERLEN.
1449 : DERLEN should be 0 if DER is NULL.
1450 :
1451 : The function returns 0 on success or an error code.
1452 : */
1453 : gpg_error_t
1454 0 : ksba_cms_add_smime_capability (ksba_cms_t cms, const char *oid,
1455 : const unsigned char *der, size_t derlen)
1456 : {
1457 : gpg_error_t err;
1458 : struct oidparmlist_s *opl, *opl2;
1459 :
1460 0 : if (!cms || !oid)
1461 0 : return gpg_error (GPG_ERR_INV_VALUE);
1462 :
1463 0 : if (!der)
1464 0 : derlen = 0;
1465 :
1466 0 : opl = xtrymalloc (sizeof *opl + derlen - 1);
1467 0 : if (!opl)
1468 0 : return gpg_error_from_errno (errno);
1469 0 : opl->next = NULL;
1470 0 : opl->oid = xtrystrdup (oid);
1471 0 : if (!opl->oid)
1472 : {
1473 0 : err = gpg_error_from_errno (errno);
1474 0 : xfree (opl);
1475 0 : return err;
1476 : }
1477 0 : opl->parmlen = derlen;
1478 0 : if (der)
1479 0 : memcpy (opl->parm, der, derlen);
1480 :
1481 : /* Append it to maintain the desired order. */
1482 0 : if (!cms->capability_list)
1483 0 : cms->capability_list = opl;
1484 : else
1485 : {
1486 0 : for (opl2=cms->capability_list; opl2->next; opl2 = opl2->next)
1487 : ;
1488 0 : opl2->next = opl;
1489 : }
1490 :
1491 0 : return 0;
1492 : }
1493 :
1494 :
1495 :
1496 : /**
1497 : * ksba_cms_set_message_digest:
1498 : * @cms: A CMS object
1499 : * @idx: The index of the signer
1500 : * @digest: a message digest
1501 : * @digest_len: the length of the message digest
1502 : *
1503 : * Set a message digest into the signedAttributes of the signer with
1504 : * the index IDX. The index of a signer is determined by the sequence
1505 : * of ksba_cms_add_signer() calls; the first signer has the index 0.
1506 : * This function is to be used when the hash value of the data has
1507 : * been calculated and before the create function requests the sign
1508 : * operation.
1509 : *
1510 : * Return value: 0 on success or an error code
1511 : **/
1512 : gpg_error_t
1513 0 : ksba_cms_set_message_digest (ksba_cms_t cms, int idx,
1514 : const unsigned char *digest, size_t digest_len)
1515 : {
1516 : struct certlist_s *cl;
1517 :
1518 0 : if (!cms || !digest)
1519 0 : return gpg_error (GPG_ERR_INV_VALUE);
1520 0 : if (!digest_len || digest_len > DIM(cl->msg_digest))
1521 0 : return gpg_error (GPG_ERR_INV_VALUE);
1522 0 : if (idx < 0)
1523 0 : return gpg_error (GPG_ERR_INV_INDEX);
1524 :
1525 0 : for (cl=cms->cert_list; cl && idx; cl = cl->next, idx--)
1526 : ;
1527 0 : if (!cl)
1528 0 : return gpg_error (GPG_ERR_INV_INDEX); /* no certificate to store it */
1529 0 : cl->msg_digest_len = digest_len;
1530 0 : memcpy (cl->msg_digest, digest, digest_len);
1531 0 : return 0;
1532 : }
1533 :
1534 : /**
1535 : * ksba_cms_set_signing_time:
1536 : * @cms: A CMS object
1537 : * @idx: The index of the signer
1538 : * @sigtime: a time or an empty value to use the current time
1539 : *
1540 : * Set a signing time into the signedAttributes of the signer with
1541 : * the index IDX. The index of a signer is determined by the sequence
1542 : * of ksba_cms_add_signer() calls; the first signer has the index 0.
1543 : *
1544 : * Return value: 0 on success or an error code
1545 : **/
1546 : gpg_error_t
1547 0 : ksba_cms_set_signing_time (ksba_cms_t cms, int idx, const ksba_isotime_t sigtime)
1548 : {
1549 : struct certlist_s *cl;
1550 :
1551 0 : if (!cms)
1552 0 : return gpg_error (GPG_ERR_INV_VALUE);
1553 0 : if (idx < 0)
1554 0 : return gpg_error (GPG_ERR_INV_INDEX);
1555 :
1556 0 : for (cl=cms->cert_list; cl && idx; cl = cl->next, idx--)
1557 : ;
1558 0 : if (!cl)
1559 0 : return gpg_error (GPG_ERR_INV_INDEX); /* no certificate to store it */
1560 :
1561 : /* Fixme: We might want to check the validity of the passed time
1562 : string. */
1563 0 : if (!*sigtime)
1564 0 : _ksba_current_time (cl->signing_time);
1565 : else
1566 0 : _ksba_copy_time (cl->signing_time, sigtime);
1567 0 : return 0;
1568 : }
1569 :
1570 :
1571 : /*
1572 : r_sig = (sig-val
1573 : (<algo>
1574 : (<param_name1> <mpi>)
1575 : ...
1576 : (<param_namen> <mpi>)
1577 : ))
1578 : The sexp must be in canonical form.
1579 : Note the <algo> must be given as a stringified OID or the special
1580 : string "rsa".
1581 :
1582 : Note that IDX is only used for consistency checks.
1583 : */
1584 : gpg_error_t
1585 0 : ksba_cms_set_sig_val (ksba_cms_t cms, int idx, ksba_const_sexp_t sigval)
1586 : {
1587 : const unsigned char *s;
1588 : unsigned long n;
1589 : struct sig_val_s *sv, **sv_tail;
1590 : int i;
1591 :
1592 0 : if (!cms)
1593 0 : return gpg_error (GPG_ERR_INV_VALUE);
1594 0 : if (idx < 0)
1595 0 : return gpg_error (GPG_ERR_INV_INDEX); /* only one signer for now */
1596 :
1597 0 : s = sigval;
1598 0 : if (*s != '(')
1599 0 : return gpg_error (GPG_ERR_INV_SEXP);
1600 0 : s++;
1601 :
1602 0 : for (i=0, sv_tail=&cms->sig_val; *sv_tail; sv_tail=&(*sv_tail)->next, i++)
1603 : ;
1604 0 : if (i != idx)
1605 0 : return gpg_error (GPG_ERR_INV_INDEX);
1606 :
1607 0 : if (!(n = snext (&s)))
1608 0 : return gpg_error (GPG_ERR_INV_SEXP);
1609 0 : if (!smatch (&s, 7, "sig-val"))
1610 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1611 0 : if (*s != '(')
1612 0 : return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
1613 0 : s++;
1614 :
1615 : /* Break out the algorithm ID. */
1616 0 : if (!(n = snext (&s)))
1617 0 : return gpg_error (GPG_ERR_INV_SEXP);
1618 :
1619 0 : sv = xtrycalloc (1, sizeof *sv);
1620 0 : if (!sv)
1621 0 : return gpg_error (GPG_ERR_ENOMEM);
1622 0 : if (n==3 && s[0] == 'r' && s[1] == 's' && s[2] == 'a')
1623 : { /* kludge to allow "rsa" to be passed as algorithm name */
1624 0 : sv->algo = xtrystrdup ("1.2.840.113549.1.1.1");
1625 0 : if (!sv->algo)
1626 : {
1627 0 : xfree (sv);
1628 0 : return gpg_error (GPG_ERR_ENOMEM);
1629 : }
1630 : }
1631 : else
1632 : {
1633 0 : sv->algo = xtrymalloc (n+1);
1634 0 : if (!sv->algo)
1635 : {
1636 0 : xfree (sv);
1637 0 : return gpg_error (GPG_ERR_ENOMEM);
1638 : }
1639 0 : memcpy (sv->algo, s, n);
1640 0 : sv->algo[n] = 0;
1641 : }
1642 0 : s += n;
1643 :
1644 : /* And now the values - FIXME: For now we only support one */
1645 : /* fixme: start loop */
1646 0 : if (*s != '(')
1647 : {
1648 0 : xfree (sv->algo);
1649 0 : xfree (sv);
1650 0 : return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
1651 : }
1652 0 : s++;
1653 :
1654 0 : if (!(n = snext (&s)))
1655 : {
1656 0 : xfree (sv->algo);
1657 0 : xfree (sv);
1658 0 : return gpg_error (GPG_ERR_INV_SEXP);
1659 : }
1660 0 : s += n; /* ignore the name of the parameter */
1661 :
1662 0 : if (!digitp(s))
1663 : {
1664 0 : xfree (sv->algo);
1665 0 : xfree (sv);
1666 : /* May also be an invalid S-EXP. */
1667 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1668 : }
1669 :
1670 0 : if (!(n = snext (&s)))
1671 : {
1672 0 : xfree (sv->algo);
1673 0 : xfree (sv);
1674 0 : return gpg_error (GPG_ERR_INV_SEXP);
1675 : }
1676 :
1677 0 : if (n > 1 && !*s)
1678 : { /* We might have a leading zero due to the way we encode
1679 : MPIs - this zero should not go into the OCTECT STRING. */
1680 0 : s++;
1681 0 : n--;
1682 : }
1683 0 : sv->value = xtrymalloc (n);
1684 0 : if (!sv->value)
1685 : {
1686 0 : xfree (sv->algo);
1687 0 : xfree (sv);
1688 0 : return gpg_error (GPG_ERR_ENOMEM);
1689 : }
1690 0 : memcpy (sv->value, s, n);
1691 0 : sv->valuelen = n;
1692 0 : s += n;
1693 0 : if ( *s != ')')
1694 : {
1695 0 : xfree (sv->value);
1696 0 : xfree (sv->algo);
1697 0 : xfree (sv);
1698 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* but may also be an invalid one */
1699 : }
1700 0 : s++;
1701 : /* fixme: end loop over parameters */
1702 :
1703 : /* we need 2 closing parenthesis */
1704 0 : if ( *s != ')' || s[1] != ')')
1705 : {
1706 0 : xfree (sv->value);
1707 0 : xfree (sv->algo);
1708 0 : xfree (sv);
1709 0 : return gpg_error (GPG_ERR_INV_SEXP);
1710 : }
1711 :
1712 0 : *sv_tail = sv;
1713 0 : return 0;
1714 : }
1715 :
1716 :
1717 : /* Set the content encryption algorithm to OID and optionally set the
1718 : initialization vector to IV */
1719 : gpg_error_t
1720 0 : ksba_cms_set_content_enc_algo (ksba_cms_t cms,
1721 : const char *oid,
1722 : const void *iv, size_t ivlen)
1723 : {
1724 0 : if (!cms || !oid)
1725 0 : return gpg_error (GPG_ERR_INV_VALUE);
1726 :
1727 0 : xfree (cms->encr_iv);
1728 0 : cms->encr_iv = NULL;
1729 0 : cms->encr_ivlen = 0;
1730 :
1731 0 : cms->encr_algo_oid = xtrystrdup (oid);
1732 0 : if (!cms->encr_algo_oid)
1733 0 : return gpg_error (GPG_ERR_ENOMEM);
1734 :
1735 0 : if (iv)
1736 : {
1737 0 : cms->encr_iv = xtrymalloc (ivlen);
1738 0 : if (!cms->encr_iv)
1739 0 : return gpg_error (GPG_ERR_ENOMEM);
1740 0 : memcpy (cms->encr_iv, iv, ivlen);
1741 0 : cms->encr_ivlen = ivlen;
1742 : }
1743 0 : return 0;
1744 : }
1745 :
1746 :
1747 : /*
1748 : * encval is expected to be a canonical encoded S-Exp of this form:
1749 : * (enc-val
1750 : * (<algo>
1751 : * (<param_name1> <mpi>)
1752 : * ...
1753 : * (<param_namen> <mpi>)
1754 : * ))
1755 : *
1756 : * Note the <algo> must be given as a stringified OID or the special
1757 : * string "rsa" */
1758 : gpg_error_t
1759 0 : ksba_cms_set_enc_val (ksba_cms_t cms, int idx, ksba_const_sexp_t encval)
1760 : {
1761 : /*FIXME: This shares most code with ...set_sig_val */
1762 : struct certlist_s *cl;
1763 : const char *s, *endp;
1764 : unsigned long n;
1765 :
1766 0 : if (!cms)
1767 0 : return gpg_error (GPG_ERR_INV_VALUE);
1768 0 : if (idx < 0)
1769 0 : return gpg_error (GPG_ERR_INV_INDEX);
1770 0 : for (cl=cms->cert_list; cl && idx; cl = cl->next, idx--)
1771 : ;
1772 0 : if (!cl)
1773 0 : return gpg_error (GPG_ERR_INV_INDEX); /* no certificate to store the value */
1774 :
1775 0 : s = encval;
1776 0 : if (*s != '(')
1777 0 : return gpg_error (GPG_ERR_INV_SEXP);
1778 0 : s++;
1779 :
1780 0 : n = strtoul (s, (char**)&endp, 10);
1781 0 : s = endp;
1782 0 : if (!n || *s!=':')
1783 0 : return gpg_error (GPG_ERR_INV_SEXP); /* we don't allow empty lengths */
1784 0 : s++;
1785 0 : if (n != 7 || memcmp (s, "enc-val", 7))
1786 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
1787 0 : s += 7;
1788 0 : if (*s != '(')
1789 0 : return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
1790 0 : s++;
1791 :
1792 : /* break out the algorithm ID */
1793 0 : n = strtoul (s, (char**)&endp, 10);
1794 0 : s = endp;
1795 0 : if (!n || *s != ':')
1796 0 : return gpg_error (GPG_ERR_INV_SEXP); /* we don't allow empty lengths */
1797 0 : s++;
1798 0 : xfree (cl->enc_val.algo);
1799 0 : if (n==3 && s[0] == 'r' && s[1] == 's' && s[2] == 'a')
1800 : { /* kludge to allow "rsa" to be passed as algorithm name */
1801 0 : cl->enc_val.algo = xtrystrdup ("1.2.840.113549.1.1.1");
1802 0 : if (!cl->enc_val.algo)
1803 0 : return gpg_error (GPG_ERR_ENOMEM);
1804 : }
1805 : else
1806 : {
1807 0 : cl->enc_val.algo = xtrymalloc (n+1);
1808 0 : if (!cl->enc_val.algo)
1809 0 : return gpg_error (GPG_ERR_ENOMEM);
1810 0 : memcpy (cl->enc_val.algo, s, n);
1811 0 : cl->enc_val.algo[n] = 0;
1812 : }
1813 0 : s += n;
1814 :
1815 : /* And now the values - FIXME: For now we only support one */
1816 : /* fixme: start loop */
1817 0 : if (*s != '(')
1818 0 : return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
1819 0 : s++;
1820 0 : n = strtoul (s, (char**)&endp, 10);
1821 0 : s = endp;
1822 0 : if (!n || *s != ':')
1823 0 : return gpg_error (GPG_ERR_INV_SEXP);
1824 0 : s++;
1825 0 : s += n; /* ignore the name of the parameter */
1826 :
1827 0 : if (!digitp(s))
1828 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* but may also be an invalid one */
1829 0 : n = strtoul (s, (char**)&endp, 10);
1830 0 : s = endp;
1831 0 : if (!n || *s != ':')
1832 0 : return gpg_error (GPG_ERR_INV_SEXP);
1833 0 : s++;
1834 0 : if (n > 1 && !*s)
1835 : { /* We might have a leading zero due to the way we encode
1836 : MPIs - this zero should not go into the OCTECT STRING. */
1837 0 : s++;
1838 0 : n--;
1839 : }
1840 0 : xfree (cl->enc_val.value);
1841 0 : cl->enc_val.value = xtrymalloc (n);
1842 0 : if (!cl->enc_val.value)
1843 0 : return gpg_error (GPG_ERR_ENOMEM);
1844 0 : memcpy (cl->enc_val.value, s, n);
1845 0 : cl->enc_val.valuelen = n;
1846 0 : s += n;
1847 0 : if ( *s != ')')
1848 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP); /* but may also be an invalid one */
1849 0 : s++;
1850 : /* fixme: end loop over parameters */
1851 :
1852 : /* we need 2 closing parenthesis */
1853 0 : if ( *s != ')' || s[1] != ')')
1854 0 : return gpg_error (GPG_ERR_INV_SEXP);
1855 :
1856 0 : return 0;
1857 : }
1858 :
1859 :
1860 :
1861 :
1862 : /**
1863 : * ksba_cms_add_recipient:
1864 : * @cms: A CMS object
1865 : * @cert: A certificate used to describe the recipient.
1866 : *
1867 : * This functions starts assembly of a new enveloped data content or adds
1868 : * another recipient to the list of recipients.
1869 : *
1870 : * Note: after successful completion of this function ownership of
1871 : * @cert is transferred to @cms.
1872 : *
1873 : * Return value: 0 on success or an error code.
1874 : **/
1875 : gpg_error_t
1876 0 : ksba_cms_add_recipient (ksba_cms_t cms, ksba_cert_t cert)
1877 : {
1878 : /* for now we use the same structure */
1879 0 : return ksba_cms_add_signer (cms, cert);
1880 : }
1881 :
1882 :
1883 :
1884 :
1885 : /*
1886 : Content handler for parsing messages
1887 : */
1888 :
1889 : static gpg_error_t
1890 0 : ct_parse_data (ksba_cms_t cms)
1891 : {
1892 : (void)cms;
1893 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
1894 : }
1895 :
1896 :
1897 : static gpg_error_t
1898 0 : ct_parse_signed_data (ksba_cms_t cms)
1899 : {
1900 : enum {
1901 : sSTART,
1902 : sGOT_HASH,
1903 : sIN_DATA,
1904 : sERROR
1905 0 : } state = sERROR;
1906 0 : ksba_stop_reason_t stop_reason = cms->stop_reason;
1907 0 : gpg_error_t err = 0;
1908 :
1909 0 : cms->stop_reason = KSBA_SR_RUNNING;
1910 :
1911 : /* Calculate state from last reason and do some checks */
1912 0 : if (stop_reason == KSBA_SR_GOT_CONTENT)
1913 : {
1914 0 : state = sSTART;
1915 : }
1916 0 : else if (stop_reason == KSBA_SR_NEED_HASH)
1917 : {
1918 0 : state = sGOT_HASH;
1919 : }
1920 0 : else if (stop_reason == KSBA_SR_BEGIN_DATA)
1921 : {
1922 0 : if (!cms->hash_fnc)
1923 0 : err = gpg_error (GPG_ERR_MISSING_ACTION);
1924 : else
1925 0 : state = sIN_DATA;
1926 : }
1927 0 : else if (stop_reason == KSBA_SR_END_DATA)
1928 : {
1929 0 : state = sGOT_HASH;
1930 : }
1931 0 : else if (stop_reason == KSBA_SR_RUNNING)
1932 0 : err = gpg_error (GPG_ERR_INV_STATE);
1933 0 : else if (stop_reason)
1934 0 : err = gpg_error (GPG_ERR_BUG);
1935 :
1936 0 : if (err)
1937 0 : return err;
1938 :
1939 : /* Do the action */
1940 0 : if (state == sSTART)
1941 0 : err = _ksba_cms_parse_signed_data_part_1 (cms);
1942 0 : else if (state == sGOT_HASH)
1943 0 : err = _ksba_cms_parse_signed_data_part_2 (cms);
1944 0 : else if (state == sIN_DATA)
1945 0 : err = read_and_hash_cont (cms);
1946 : else
1947 0 : err = gpg_error (GPG_ERR_INV_STATE);
1948 :
1949 0 : if (err)
1950 0 : return err;
1951 :
1952 : /* Calculate new stop reason */
1953 0 : if (state == sSTART)
1954 : {
1955 0 : if (cms->detached_data && !cms->data.digest)
1956 : { /* We use this stop reason to inform the caller about a
1957 : detached signatures. Actually there is no need for him
1958 : to hash the data now, he can do this also later. */
1959 0 : stop_reason = KSBA_SR_NEED_HASH;
1960 : }
1961 : else
1962 : { /* The user must now provide a hash function so that we can
1963 : hash the data in the next round */
1964 0 : stop_reason = KSBA_SR_BEGIN_DATA;
1965 : }
1966 : }
1967 0 : else if (state == sIN_DATA)
1968 0 : stop_reason = KSBA_SR_END_DATA;
1969 0 : else if (state ==sGOT_HASH)
1970 0 : stop_reason = KSBA_SR_READY;
1971 :
1972 0 : cms->stop_reason = stop_reason;
1973 0 : return 0;
1974 : }
1975 :
1976 :
1977 : static gpg_error_t
1978 0 : ct_parse_enveloped_data (ksba_cms_t cms)
1979 : {
1980 : enum {
1981 : sSTART,
1982 : sREST,
1983 : sINDATA,
1984 : sERROR
1985 0 : } state = sERROR;
1986 0 : ksba_stop_reason_t stop_reason = cms->stop_reason;
1987 0 : gpg_error_t err = 0;
1988 :
1989 0 : cms->stop_reason = KSBA_SR_RUNNING;
1990 :
1991 : /* Calculate state from last reason and do some checks */
1992 0 : if (stop_reason == KSBA_SR_GOT_CONTENT)
1993 : {
1994 0 : state = sSTART;
1995 : }
1996 0 : else if (stop_reason == KSBA_SR_DETACHED_DATA)
1997 : {
1998 0 : state = sREST;
1999 : }
2000 0 : else if (stop_reason == KSBA_SR_BEGIN_DATA)
2001 : {
2002 0 : state = sINDATA;
2003 : }
2004 0 : else if (stop_reason == KSBA_SR_END_DATA)
2005 : {
2006 0 : state = sREST;
2007 : }
2008 0 : else if (stop_reason == KSBA_SR_RUNNING)
2009 0 : err = gpg_error (GPG_ERR_INV_STATE);
2010 0 : else if (stop_reason)
2011 0 : err = gpg_error (GPG_ERR_BUG);
2012 :
2013 0 : if (err)
2014 0 : return err;
2015 :
2016 : /* Do the action */
2017 0 : if (state == sSTART)
2018 0 : err = _ksba_cms_parse_enveloped_data_part_1 (cms);
2019 0 : else if (state == sREST)
2020 0 : err = _ksba_cms_parse_enveloped_data_part_2 (cms);
2021 0 : else if (state == sINDATA)
2022 0 : err = read_encrypted_cont (cms);
2023 : else
2024 0 : err = gpg_error (GPG_ERR_INV_STATE);
2025 :
2026 0 : if (err)
2027 0 : return err;
2028 :
2029 : /* Calculate new stop reason */
2030 0 : if (state == sSTART)
2031 : {
2032 0 : stop_reason = cms->detached_data? KSBA_SR_DETACHED_DATA
2033 0 : : KSBA_SR_BEGIN_DATA;
2034 : }
2035 0 : else if (state == sINDATA)
2036 0 : stop_reason = KSBA_SR_END_DATA;
2037 0 : else if (state ==sREST)
2038 0 : stop_reason = KSBA_SR_READY;
2039 :
2040 0 : cms->stop_reason = stop_reason;
2041 0 : return 0;
2042 : }
2043 :
2044 :
2045 : static gpg_error_t
2046 0 : ct_parse_digested_data (ksba_cms_t cms)
2047 : {
2048 : (void)cms;
2049 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2050 : }
2051 :
2052 :
2053 : static gpg_error_t
2054 0 : ct_parse_encrypted_data (ksba_cms_t cms)
2055 : {
2056 : (void)cms;
2057 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2058 : }
2059 :
2060 :
2061 :
2062 : /*
2063 : Content handlers for building messages
2064 : */
2065 :
2066 : static gpg_error_t
2067 0 : ct_build_data (ksba_cms_t cms)
2068 : {
2069 : (void)cms;
2070 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2071 : }
2072 :
2073 :
2074 :
2075 : /* Write everything up to the encapsulated data content type. */
2076 : static gpg_error_t
2077 0 : build_signed_data_header (ksba_cms_t cms)
2078 : {
2079 : gpg_error_t err;
2080 : unsigned char *buf;
2081 : const char *s;
2082 : size_t len;
2083 : int i;
2084 :
2085 : /* Write the outer contentInfo. */
2086 0 : err = _ksba_ber_write_tl (cms->writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, 0);
2087 0 : if (err)
2088 0 : return err;
2089 0 : err = ksba_oid_from_str (cms->content.oid, &buf, &len);
2090 0 : if (err)
2091 0 : return err;
2092 0 : err = _ksba_ber_write_tl (cms->writer,
2093 : TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, len);
2094 0 : if (!err)
2095 0 : err = ksba_writer_write (cms->writer, buf, len);
2096 0 : xfree (buf);
2097 0 : if (err)
2098 0 : return err;
2099 :
2100 0 : err = _ksba_ber_write_tl (cms->writer, 0, CLASS_CONTEXT, 1, 0);
2101 0 : if (err)
2102 0 : return err;
2103 :
2104 : /* The SEQUENCE */
2105 0 : err = _ksba_ber_write_tl (cms->writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, 0);
2106 0 : if (err)
2107 0 : return err;
2108 :
2109 : /* figure out the CMSVersion to be used */
2110 : if (0 /* fixme: have_attribute_certificates
2111 : || encapsulated_content != data
2112 : || any_signer_info_is_version_3*/ )
2113 : s = "\x03";
2114 : else
2115 0 : s = "\x01";
2116 0 : err = _ksba_ber_write_tl (cms->writer, TYPE_INTEGER, CLASS_UNIVERSAL, 0, 1);
2117 0 : if (err)
2118 0 : return err;
2119 0 : err = ksba_writer_write (cms->writer, s, 1);
2120 0 : if (err)
2121 0 : return err;
2122 :
2123 : /* SET OF DigestAlgorithmIdentifier */
2124 : {
2125 : unsigned char *value;
2126 : size_t valuelen;
2127 : ksba_writer_t tmpwrt;
2128 :
2129 0 : err = ksba_writer_new (&tmpwrt);
2130 0 : if (err)
2131 0 : return err;
2132 0 : err = ksba_writer_set_mem (tmpwrt, 512);
2133 0 : if (err)
2134 : {
2135 0 : ksba_writer_release (tmpwrt);
2136 0 : return err;
2137 : }
2138 :
2139 0 : for (i=0; (s = ksba_cms_get_digest_algo_list (cms, i)); i++)
2140 : {
2141 : int j;
2142 : const char *s2;
2143 :
2144 : /* (make sure not to write duplicates) */
2145 0 : for (j=0; j < i && (s2=ksba_cms_get_digest_algo_list (cms, j)); j++)
2146 : {
2147 0 : if (!strcmp (s, s2))
2148 0 : break;
2149 : }
2150 0 : if (j == i)
2151 : {
2152 0 : err = _ksba_der_write_algorithm_identifier (tmpwrt, s, NULL, 0);
2153 0 : if (err)
2154 : {
2155 0 : ksba_writer_release (tmpwrt);
2156 0 : return err;
2157 : }
2158 : }
2159 : }
2160 :
2161 0 : value = ksba_writer_snatch_mem (tmpwrt, &valuelen);
2162 0 : ksba_writer_release (tmpwrt);
2163 0 : if (!value)
2164 : {
2165 0 : err = gpg_error (GPG_ERR_ENOMEM);
2166 0 : return err;
2167 : }
2168 0 : err = _ksba_ber_write_tl (cms->writer, TYPE_SET, CLASS_UNIVERSAL,
2169 : 1, valuelen);
2170 0 : if (!err)
2171 0 : err = ksba_writer_write (cms->writer, value, valuelen);
2172 0 : xfree (value);
2173 0 : if (err)
2174 0 : return err;
2175 : }
2176 :
2177 :
2178 :
2179 : /* Write the (inner) encapsulatedContentInfo */
2180 : /* if we have a detached signature we don't need to use undefinite
2181 : length here - but it doesn't matter either */
2182 0 : err = _ksba_ber_write_tl (cms->writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, 0);
2183 0 : if (err)
2184 0 : return err;
2185 0 : err = ksba_oid_from_str (cms->inner_cont_oid, &buf, &len);
2186 0 : if (err)
2187 0 : return err;
2188 0 : err = _ksba_ber_write_tl (cms->writer,
2189 : TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, len);
2190 0 : if (!err)
2191 0 : err = ksba_writer_write (cms->writer, buf, len);
2192 0 : xfree (buf);
2193 0 : if (err)
2194 0 : return err;
2195 :
2196 0 : if ( !cms->detached_data)
2197 : { /* write the tag */
2198 0 : err = _ksba_ber_write_tl (cms->writer, 0, CLASS_CONTEXT, 1, 0);
2199 0 : if (err)
2200 0 : return err;
2201 : }
2202 :
2203 0 : return err;
2204 : }
2205 :
2206 : /* Set the issuer/serial from the cert to the node.
2207 : mode 0: sid
2208 : mode 1: rid
2209 : */
2210 : static gpg_error_t
2211 0 : set_issuer_serial (AsnNode info, ksba_cert_t cert, int mode)
2212 : {
2213 : gpg_error_t err;
2214 : AsnNode dst, src;
2215 :
2216 0 : if (!info || !cert)
2217 0 : return gpg_error (GPG_ERR_INV_VALUE);
2218 :
2219 0 : src = _ksba_asn_find_node (cert->root,
2220 : "Certificate.tbsCertificate.serialNumber");
2221 0 : dst = _ksba_asn_find_node (info,
2222 : mode?
2223 : "rid.issuerAndSerialNumber.serialNumber":
2224 : "sid.issuerAndSerialNumber.serialNumber");
2225 0 : err = _ksba_der_copy_tree (dst, src, cert->image);
2226 0 : if (err)
2227 0 : return err;
2228 :
2229 0 : src = _ksba_asn_find_node (cert->root,
2230 : "Certificate.tbsCertificate.issuer");
2231 0 : dst = _ksba_asn_find_node (info,
2232 : mode?
2233 : "rid.issuerAndSerialNumber.issuer":
2234 : "sid.issuerAndSerialNumber.issuer");
2235 0 : err = _ksba_der_copy_tree (dst, src, cert->image);
2236 0 : if (err)
2237 0 : return err;
2238 :
2239 0 : return 0;
2240 : }
2241 :
2242 :
2243 : /* Store the sequence of capabilities at NODE */
2244 : static gpg_error_t
2245 0 : store_smime_capability_sequence (AsnNode node,
2246 : struct oidparmlist_s *capabilities)
2247 : {
2248 : gpg_error_t err;
2249 : struct oidparmlist_s *cap, *cap2;
2250 : unsigned char *value;
2251 : size_t valuelen;
2252 : ksba_writer_t tmpwrt;
2253 :
2254 0 : err = ksba_writer_new (&tmpwrt);
2255 0 : if (err)
2256 0 : return err;
2257 0 : err = ksba_writer_set_mem (tmpwrt, 512);
2258 0 : if (err)
2259 : {
2260 0 : ksba_writer_release (tmpwrt);
2261 0 : return err;
2262 : }
2263 :
2264 0 : for (cap=capabilities; cap; cap = cap->next)
2265 : {
2266 : /* (avoid writing duplicates) */
2267 0 : for (cap2=capabilities; cap2 != cap; cap2 = cap2->next)
2268 : {
2269 0 : if (!strcmp (cap->oid, cap2->oid)
2270 0 : && cap->parmlen && cap->parmlen == cap2->parmlen
2271 0 : && !memcmp (cap->parm, cap2->parm, cap->parmlen))
2272 0 : break; /* Duplicate found. */
2273 : }
2274 0 : if (cap2 == cap)
2275 : {
2276 : /* RFC3851 requires that a missing parameter must not be
2277 : encoded as NULL. This is in contrast to all other usages
2278 : of the algorithm identifier where ist is allowed and in
2279 : some profiles (e.g. tmttv2) even explicitly suggested to
2280 : use NULL. */
2281 0 : err = _ksba_der_write_algorithm_identifier
2282 0 : (tmpwrt, cap->oid,
2283 0 : cap->parmlen?cap->parm:(const void*)"", cap->parmlen);
2284 0 : if (err)
2285 : {
2286 0 : ksba_writer_release (tmpwrt);
2287 0 : return err;
2288 : }
2289 : }
2290 : }
2291 :
2292 0 : value = ksba_writer_snatch_mem (tmpwrt, &valuelen);
2293 0 : if (!value)
2294 0 : err = gpg_error (GPG_ERR_ENOMEM);
2295 0 : if (!err)
2296 0 : err = _ksba_der_store_sequence (node, value, valuelen);
2297 0 : xfree (value);
2298 0 : ksba_writer_release (tmpwrt);
2299 0 : return err;
2300 : }
2301 :
2302 :
2303 : /* An object used to construct the signed attributes. */
2304 : struct attrarray_s {
2305 : AsnNode root;
2306 : unsigned char *image;
2307 : size_t imagelen;
2308 : };
2309 :
2310 :
2311 : /* Thank you ASN.1 committee for allowing us to employ a sort to make
2312 : that DER encoding even more complicate. */
2313 : static int
2314 0 : compare_attrarray (const void *a_v, const void *b_v)
2315 : {
2316 0 : const struct attrarray_s *a = a_v;
2317 0 : const struct attrarray_s *b = b_v;
2318 : const unsigned char *ap, *bp;
2319 : size_t an, bn;
2320 :
2321 0 : ap = a->image;
2322 0 : an = a->imagelen;
2323 0 : bp = b->image;
2324 0 : bn = b->imagelen;
2325 0 : for (; an && bn; an--, bn--, ap++, bp++ )
2326 0 : if (*ap != *bp)
2327 0 : return *ap - *bp;
2328 :
2329 0 : return (an == bn)? 0 : (an > bn)? 1 : -1;
2330 : }
2331 :
2332 :
2333 :
2334 :
2335 : /* Write the END of data NULL tag and everything we can write before
2336 : the user can calculate the signature */
2337 : static gpg_error_t
2338 0 : build_signed_data_attributes (ksba_cms_t cms)
2339 : {
2340 : gpg_error_t err;
2341 : int signer;
2342 0 : ksba_asn_tree_t cms_tree = NULL;
2343 : struct certlist_s *certlist;
2344 : struct oidlist_s *digestlist;
2345 : struct signer_info_s *si, **si_tail;
2346 0 : AsnNode root = NULL;
2347 : struct attrarray_s attrarray[4];
2348 0 : int attridx = 0;
2349 : int i;
2350 :
2351 0 : memset (attrarray, 0, sizeof (attrarray));
2352 :
2353 : /* Write the End tag */
2354 0 : err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
2355 0 : if (err)
2356 0 : return err;
2357 :
2358 0 : if (cms->signer_info)
2359 0 : return gpg_error (GPG_ERR_CONFLICT); /* This list must be empty at
2360 : this point. */
2361 :
2362 : /* Write optional certificates */
2363 0 : if (cms->cert_info_list)
2364 : {
2365 0 : unsigned long totallen = 0;
2366 : const unsigned char *der;
2367 : size_t n;
2368 :
2369 0 : for (certlist = cms->cert_info_list; certlist; certlist = certlist->next)
2370 : {
2371 0 : if (!ksba_cert_get_image (certlist->cert, &n))
2372 0 : return gpg_error (GPG_ERR_GENERAL); /* User passed an
2373 : unitialized cert */
2374 0 : totallen += n;
2375 : }
2376 :
2377 0 : err = _ksba_ber_write_tl (cms->writer, 0, CLASS_CONTEXT, 1, totallen);
2378 0 : if (err)
2379 0 : return err;
2380 :
2381 0 : for (certlist = cms->cert_info_list; certlist; certlist = certlist->next)
2382 : {
2383 0 : if (!(der=ksba_cert_get_image (certlist->cert, &n)))
2384 0 : return gpg_error (GPG_ERR_BUG);
2385 0 : err = ksba_writer_write (cms->writer, der, n);
2386 0 : if (err )
2387 0 : return err;
2388 : }
2389 : }
2390 :
2391 : /* If we ever support it, here is the right place to do it:
2392 : Write the optional CRLs */
2393 :
2394 : /* Now we have to prepare the signer info. For now we will just build the
2395 : signedAttributes, so that the user can do the signature calculation */
2396 0 : err = ksba_asn_create_tree ("cms", &cms_tree);
2397 0 : if (err)
2398 0 : return err;
2399 :
2400 0 : certlist = cms->cert_list;
2401 0 : if (!certlist)
2402 : {
2403 0 : err = gpg_error (GPG_ERR_MISSING_VALUE); /* oops */
2404 0 : goto leave;
2405 : }
2406 0 : digestlist = cms->digest_algos;
2407 0 : if (!digestlist)
2408 : {
2409 0 : err = gpg_error (GPG_ERR_MISSING_VALUE); /* oops */
2410 0 : goto leave;
2411 : }
2412 :
2413 0 : si_tail = &cms->signer_info;
2414 0 : for (signer=0; certlist;
2415 0 : signer++, certlist = certlist->next, digestlist = digestlist->next)
2416 : {
2417 : AsnNode attr;
2418 : AsnNode n;
2419 : unsigned char *image;
2420 : size_t imagelen;
2421 :
2422 0 : for (i = 0; i < attridx; i++)
2423 : {
2424 0 : _ksba_asn_release_nodes (attrarray[i].root);
2425 0 : xfree (attrarray[i].image);
2426 : }
2427 0 : attridx = 0;
2428 0 : memset (attrarray, 0, sizeof (attrarray));
2429 :
2430 0 : if (!digestlist)
2431 : {
2432 0 : err = gpg_error (GPG_ERR_MISSING_VALUE); /* oops */
2433 0 : goto leave;
2434 : }
2435 :
2436 0 : if (!certlist->cert || !digestlist->oid)
2437 : {
2438 0 : err = gpg_error (GPG_ERR_BUG);
2439 0 : goto leave;
2440 : }
2441 :
2442 : /* Include the pretty important message digest. */
2443 0 : attr = _ksba_asn_expand_tree (cms_tree->parse_tree,
2444 : "CryptographicMessageSyntax.Attribute");
2445 0 : if (!attr)
2446 : {
2447 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2448 0 : goto leave;
2449 : }
2450 0 : n = _ksba_asn_find_node (attr, "Attribute.attrType");
2451 0 : if (!n)
2452 : {
2453 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2454 0 : goto leave;
2455 : }
2456 0 : err = _ksba_der_store_oid (n, oidstr_messageDigest);
2457 0 : if (err)
2458 0 : goto leave;
2459 0 : n = _ksba_asn_find_node (attr, "Attribute.attrValues");
2460 0 : if (!n || !n->down)
2461 0 : return gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2462 0 : n = n->down; /* fixme: ugly hack */
2463 0 : assert (certlist && certlist->msg_digest_len);
2464 0 : err = _ksba_der_store_octet_string (n, certlist->msg_digest,
2465 0 : certlist->msg_digest_len);
2466 0 : if (err)
2467 0 : goto leave;
2468 0 : err = _ksba_der_encode_tree (attr, &image, &imagelen);
2469 0 : if (err)
2470 0 : goto leave;
2471 0 : attrarray[attridx].root = attr;
2472 0 : attrarray[attridx].image = image;
2473 0 : attrarray[attridx].imagelen = imagelen;
2474 0 : attridx++;
2475 :
2476 : /* Include the content-type attribute. */
2477 0 : attr = _ksba_asn_expand_tree (cms_tree->parse_tree,
2478 : "CryptographicMessageSyntax.Attribute");
2479 0 : if (!attr)
2480 : {
2481 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2482 0 : goto leave;
2483 : }
2484 0 : n = _ksba_asn_find_node (attr, "Attribute.attrType");
2485 0 : if (!n)
2486 : {
2487 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2488 0 : goto leave;
2489 : }
2490 0 : err = _ksba_der_store_oid (n, oidstr_contentType);
2491 0 : if (err)
2492 0 : goto leave;
2493 0 : n = _ksba_asn_find_node (attr, "Attribute.attrValues");
2494 0 : if (!n || !n->down)
2495 : {
2496 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2497 0 : goto leave;
2498 : }
2499 0 : n = n->down; /* fixme: ugly hack */
2500 0 : err = _ksba_der_store_oid (n, cms->inner_cont_oid);
2501 0 : if (err)
2502 0 : goto leave;
2503 0 : err = _ksba_der_encode_tree (attr, &image, &imagelen);
2504 0 : if (err)
2505 0 : goto leave;
2506 0 : attrarray[attridx].root = attr;
2507 0 : attrarray[attridx].image = image;
2508 0 : attrarray[attridx].imagelen = imagelen;
2509 0 : attridx++;
2510 :
2511 : /* Include the signing time */
2512 0 : if (certlist->signing_time)
2513 : {
2514 0 : attr = _ksba_asn_expand_tree (cms_tree->parse_tree,
2515 : "CryptographicMessageSyntax.Attribute");
2516 0 : if (!attr)
2517 : {
2518 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2519 0 : goto leave;
2520 : }
2521 0 : n = _ksba_asn_find_node (attr, "Attribute.attrType");
2522 0 : if (!n)
2523 : {
2524 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2525 0 : goto leave;
2526 : }
2527 0 : err = _ksba_der_store_oid (n, oidstr_signingTime);
2528 0 : if (err)
2529 0 : goto leave;
2530 0 : n = _ksba_asn_find_node (attr, "Attribute.attrValues");
2531 0 : if (!n || !n->down)
2532 : {
2533 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2534 0 : goto leave;
2535 : }
2536 0 : n = n->down; /* fixme: ugly hack */
2537 0 : err = _ksba_der_store_time (n, certlist->signing_time);
2538 0 : if (err)
2539 0 : goto leave;
2540 0 : err = _ksba_der_encode_tree (attr, &image, &imagelen);
2541 0 : if (err)
2542 0 : goto leave;
2543 : /* We will use the attributes again - so save them */
2544 0 : attrarray[attridx].root = attr;
2545 0 : attrarray[attridx].image = image;
2546 0 : attrarray[attridx].imagelen = imagelen;
2547 0 : attridx++;
2548 : }
2549 :
2550 : /* Include the S/MIME capabilities with the first signer. */
2551 0 : if (cms->capability_list && !signer)
2552 : {
2553 0 : attr = _ksba_asn_expand_tree (cms_tree->parse_tree,
2554 : "CryptographicMessageSyntax.Attribute");
2555 0 : if (!attr)
2556 : {
2557 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2558 0 : goto leave;
2559 : }
2560 0 : n = _ksba_asn_find_node (attr, "Attribute.attrType");
2561 0 : if (!n)
2562 : {
2563 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2564 0 : goto leave;
2565 : }
2566 0 : err = _ksba_der_store_oid (n, oidstr_smimeCapabilities);
2567 0 : if (err)
2568 0 : goto leave;
2569 0 : n = _ksba_asn_find_node (attr, "Attribute.attrValues");
2570 0 : if (!n || !n->down)
2571 : {
2572 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2573 0 : goto leave;
2574 : }
2575 0 : n = n->down; /* fixme: ugly hack */
2576 0 : err = store_smime_capability_sequence (n, cms->capability_list);
2577 0 : if (err)
2578 0 : goto leave;
2579 0 : err = _ksba_der_encode_tree (attr, &image, &imagelen);
2580 0 : if (err)
2581 0 : goto leave;
2582 0 : attrarray[attridx].root = attr;
2583 0 : attrarray[attridx].image = image;
2584 0 : attrarray[attridx].imagelen = imagelen;
2585 0 : attridx++;
2586 : }
2587 :
2588 : /* Arggh. That silly ASN.1 DER encoding rules: We need to sort
2589 : the SET values. */
2590 0 : qsort (attrarray, attridx, sizeof (struct attrarray_s),
2591 : compare_attrarray);
2592 :
2593 : /* Now copy them to an SignerInfo tree. This tree is not
2594 : complete but suitable for ksba_cms_hash_signed_attributes() */
2595 0 : root = _ksba_asn_expand_tree (cms_tree->parse_tree,
2596 : "CryptographicMessageSyntax.SignerInfo");
2597 0 : n = _ksba_asn_find_node (root, "SignerInfo.signedAttrs");
2598 0 : if (!n || !n->down)
2599 : {
2600 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2601 0 : goto leave;
2602 : }
2603 : /* This is another ugly hack to move to the element we want */
2604 0 : for (n = n->down->down; n && n->type != TYPE_SEQUENCE; n = n->right)
2605 : ;
2606 0 : if (!n)
2607 : {
2608 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2609 0 : goto leave;
2610 : }
2611 :
2612 0 : assert (attridx <= DIM (attrarray));
2613 0 : for (i=0; i < attridx; i++)
2614 : {
2615 0 : if (i)
2616 : {
2617 0 : if ( !(n=_ksba_asn_insert_copy (n)))
2618 : {
2619 0 : err = gpg_error (GPG_ERR_ENOMEM);
2620 0 : goto leave;
2621 : }
2622 : }
2623 0 : err = _ksba_der_copy_tree (n, attrarray[i].root, attrarray[i].image);
2624 0 : if (err)
2625 0 : goto leave;
2626 0 : _ksba_asn_release_nodes (attrarray[i].root);
2627 0 : free (attrarray[i].image);
2628 0 : attrarray[i].root = NULL;
2629 0 : attrarray[i].image = NULL;
2630 : }
2631 :
2632 0 : err = _ksba_der_encode_tree (root, &image, NULL);
2633 0 : if (err)
2634 0 : goto leave;
2635 :
2636 0 : si = xtrycalloc (1, sizeof *si);
2637 0 : if (!si)
2638 0 : return gpg_error (GPG_ERR_ENOMEM);
2639 0 : si->root = root;
2640 0 : root = NULL;
2641 0 : si->image = image;
2642 : /* Hmmm, we don't set the length of the image. */
2643 0 : *si_tail = si;
2644 0 : si_tail = &si->next;
2645 : }
2646 :
2647 : leave:
2648 0 : _ksba_asn_release_nodes (root);
2649 0 : ksba_asn_tree_release (cms_tree);
2650 0 : for (i = 0; i < attridx; i++)
2651 : {
2652 0 : _ksba_asn_release_nodes (attrarray[i].root);
2653 0 : xfree (attrarray[i].image);
2654 : }
2655 :
2656 0 : return err;
2657 : }
2658 :
2659 :
2660 :
2661 :
2662 : /* The user has calculated the signatures and we can therefore write
2663 : everything left over to do. */
2664 : static gpg_error_t
2665 0 : build_signed_data_rest (ksba_cms_t cms)
2666 : {
2667 : gpg_error_t err;
2668 : int signer;
2669 0 : ksba_asn_tree_t cms_tree = NULL;
2670 : struct certlist_s *certlist;
2671 : struct oidlist_s *digestlist;
2672 : struct signer_info_s *si;
2673 : struct sig_val_s *sv;
2674 0 : ksba_writer_t tmpwrt = NULL;
2675 0 : AsnNode root = NULL;
2676 :
2677 : /* Now we can really write the signer info */
2678 0 : err = ksba_asn_create_tree ("cms", &cms_tree);
2679 0 : if (err)
2680 0 : return err;
2681 :
2682 0 : certlist = cms->cert_list;
2683 0 : if (!certlist)
2684 : {
2685 0 : err = gpg_error (GPG_ERR_MISSING_VALUE); /* oops */
2686 0 : return err;
2687 : }
2688 :
2689 : /* To construct the set we use a temporary writer object. */
2690 0 : err = ksba_writer_new (&tmpwrt);
2691 0 : if (err)
2692 0 : goto leave;
2693 0 : err = ksba_writer_set_mem (tmpwrt, 2048);
2694 0 : if (err)
2695 0 : goto leave;
2696 :
2697 0 : digestlist = cms->digest_algos;
2698 0 : si = cms->signer_info;
2699 0 : sv = cms->sig_val;
2700 :
2701 0 : for (signer=0; certlist;
2702 0 : signer++,
2703 0 : certlist = certlist->next,
2704 0 : digestlist = digestlist->next,
2705 0 : si = si->next,
2706 0 : sv = sv->next)
2707 : {
2708 : AsnNode n, n2;
2709 : unsigned char *image;
2710 : size_t imagelen;
2711 :
2712 0 : if (!digestlist || !si || !sv)
2713 : {
2714 0 : err = gpg_error (GPG_ERR_MISSING_VALUE); /* oops */
2715 0 : goto leave;
2716 : }
2717 0 : if (!certlist->cert || !digestlist->oid)
2718 : {
2719 0 : err = gpg_error (GPG_ERR_BUG);
2720 0 : goto leave;
2721 : }
2722 :
2723 0 : root = _ksba_asn_expand_tree (cms_tree->parse_tree,
2724 : "CryptographicMessageSyntax.SignerInfo");
2725 :
2726 : /* We store a version of 1 because we use the issuerAndSerialNumber */
2727 0 : n = _ksba_asn_find_node (root, "SignerInfo.version");
2728 0 : if (!n)
2729 : {
2730 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2731 0 : goto leave;
2732 : }
2733 0 : err = _ksba_der_store_integer (n, "\x00\x00\x00\x01\x01");
2734 0 : if (err)
2735 0 : goto leave;
2736 :
2737 : /* Store the sid */
2738 0 : n = _ksba_asn_find_node (root, "SignerInfo.sid");
2739 0 : if (!n)
2740 : {
2741 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2742 0 : goto leave;
2743 : }
2744 :
2745 0 : err = set_issuer_serial (n, certlist->cert, 0);
2746 0 : if (err)
2747 0 : goto leave;
2748 :
2749 : /* store the digestAlgorithm */
2750 0 : n = _ksba_asn_find_node (root, "SignerInfo.digestAlgorithm.algorithm");
2751 0 : if (!n)
2752 : {
2753 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2754 0 : goto leave;
2755 : }
2756 0 : err = _ksba_der_store_oid (n, digestlist->oid);
2757 0 : if (err)
2758 0 : goto leave;
2759 0 : n = _ksba_asn_find_node (root, "SignerInfo.digestAlgorithm.parameters");
2760 0 : if (!n)
2761 : {
2762 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2763 0 : goto leave;
2764 : }
2765 0 : err = _ksba_der_store_null (n);
2766 0 : if (err)
2767 0 : goto leave;
2768 :
2769 : /* and the signed attributes */
2770 0 : n = _ksba_asn_find_node (root, "SignerInfo.signedAttrs");
2771 0 : if (!n || !n->down)
2772 : {
2773 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2774 0 : goto leave;
2775 : }
2776 0 : assert (si->root);
2777 0 : assert (si->image);
2778 0 : n2 = _ksba_asn_find_node (si->root, "SignerInfo.signedAttrs");
2779 0 : if (!n2 || !n->down)
2780 : {
2781 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2782 0 : goto leave;
2783 : }
2784 0 : err = _ksba_der_copy_tree (n, n2, si->image);
2785 0 : if (err)
2786 0 : goto leave;
2787 0 : image = NULL;
2788 :
2789 : /* store the signatureAlgorithm */
2790 0 : n = _ksba_asn_find_node (root,
2791 : "SignerInfo.signatureAlgorithm.algorithm");
2792 0 : if (!n)
2793 : {
2794 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2795 0 : goto leave;
2796 : }
2797 0 : if (!sv->algo)
2798 : {
2799 0 : err = gpg_error (GPG_ERR_MISSING_VALUE);
2800 0 : goto leave;
2801 : }
2802 0 : err = _ksba_der_store_oid (n, sv->algo);
2803 0 : if (err)
2804 0 : goto leave;
2805 0 : n = _ksba_asn_find_node (root,
2806 : "SignerInfo.signatureAlgorithm.parameters");
2807 0 : if (!n)
2808 : {
2809 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2810 0 : goto leave;
2811 : }
2812 0 : err = _ksba_der_store_null (n);
2813 0 : if (err)
2814 0 : goto leave;
2815 :
2816 : /* store the signature */
2817 0 : if (!sv->value)
2818 : {
2819 0 : err = gpg_error (GPG_ERR_MISSING_VALUE);
2820 0 : goto leave;
2821 : }
2822 0 : n = _ksba_asn_find_node (root, "SignerInfo.signature");
2823 0 : if (!n)
2824 : {
2825 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
2826 0 : goto leave;
2827 : }
2828 0 : err = _ksba_der_store_octet_string (n, sv->value, sv->valuelen);
2829 0 : if (err)
2830 0 : goto leave;
2831 :
2832 : /* Make the DER encoding and write it out. */
2833 0 : err = _ksba_der_encode_tree (root, &image, &imagelen);
2834 0 : if (err)
2835 0 : goto leave;
2836 :
2837 0 : err = ksba_writer_write (tmpwrt, image, imagelen);
2838 0 : xfree (image);
2839 0 : if (err)
2840 0 : goto leave;
2841 : }
2842 :
2843 : /* Write out the SET filled with all signer infos */
2844 : {
2845 : unsigned char *value;
2846 : size_t valuelen;
2847 :
2848 0 : value = ksba_writer_snatch_mem (tmpwrt, &valuelen);
2849 0 : if (!value)
2850 : {
2851 0 : err = gpg_error (GPG_ERR_ENOMEM);
2852 0 : goto leave;
2853 : }
2854 0 : err = _ksba_ber_write_tl (cms->writer, TYPE_SET, CLASS_UNIVERSAL,
2855 : 1, valuelen);
2856 0 : if (!err)
2857 0 : err = ksba_writer_write (cms->writer, value, valuelen);
2858 0 : xfree (value);
2859 0 : if (err)
2860 0 : goto leave;
2861 : }
2862 :
2863 : /* Write 3 end tags */
2864 0 : err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
2865 0 : if (!err)
2866 0 : err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
2867 0 : if (!err)
2868 0 : err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
2869 :
2870 : leave:
2871 0 : ksba_asn_tree_release (cms_tree);
2872 0 : _ksba_asn_release_nodes (root);
2873 0 : ksba_writer_release (tmpwrt);
2874 :
2875 0 : return err;
2876 : }
2877 :
2878 :
2879 :
2880 :
2881 : static gpg_error_t
2882 0 : ct_build_signed_data (ksba_cms_t cms)
2883 : {
2884 : enum {
2885 : sSTART,
2886 : sDATAREADY,
2887 : sGOTSIG,
2888 : sERROR
2889 0 : } state = sERROR;
2890 : ksba_stop_reason_t stop_reason;
2891 0 : gpg_error_t err = 0;
2892 :
2893 0 : stop_reason = cms->stop_reason;
2894 0 : cms->stop_reason = KSBA_SR_RUNNING;
2895 :
2896 : /* Calculate state from last reason and do some checks */
2897 0 : if (stop_reason == KSBA_SR_GOT_CONTENT)
2898 : {
2899 0 : state = sSTART;
2900 : }
2901 0 : else if (stop_reason == KSBA_SR_BEGIN_DATA)
2902 : {
2903 : /* fixme: check that the message digest has been set */
2904 0 : state = sDATAREADY;
2905 : }
2906 0 : else if (stop_reason == KSBA_SR_END_DATA)
2907 0 : state = sDATAREADY;
2908 0 : else if (stop_reason == KSBA_SR_NEED_SIG)
2909 : {
2910 0 : if (!cms->sig_val)
2911 0 : err = gpg_error (GPG_ERR_MISSING_ACTION); /* No ksba_cms_set_sig_val () called */
2912 0 : state = sGOTSIG;
2913 : }
2914 0 : else if (stop_reason == KSBA_SR_RUNNING)
2915 0 : err = gpg_error (GPG_ERR_INV_STATE);
2916 0 : else if (stop_reason)
2917 0 : err = gpg_error (GPG_ERR_BUG);
2918 :
2919 0 : if (err)
2920 0 : return err;
2921 :
2922 : /* Do the action */
2923 0 : if (state == sSTART)
2924 : {
2925 : /* figure out whether a detached signature is requested */
2926 0 : if (cms->cert_list && cms->cert_list->msg_digest_len)
2927 0 : cms->detached_data = 1;
2928 : else
2929 0 : cms->detached_data = 0;
2930 : /* and start encoding */
2931 0 : err = build_signed_data_header (cms);
2932 : }
2933 0 : else if (state == sDATAREADY)
2934 : {
2935 0 : if (!cms->detached_data)
2936 0 : err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
2937 0 : if (!err)
2938 0 : err = build_signed_data_attributes (cms);
2939 : }
2940 0 : else if (state == sGOTSIG)
2941 0 : err = build_signed_data_rest (cms);
2942 : else
2943 0 : err = gpg_error (GPG_ERR_INV_STATE);
2944 :
2945 0 : if (err)
2946 0 : return err;
2947 :
2948 : /* Calculate new stop reason */
2949 0 : if (state == sSTART)
2950 : {
2951 : /* user should write the data and calculate the hash or do
2952 : nothing in case of END_DATA */
2953 0 : stop_reason = cms->detached_data? KSBA_SR_END_DATA
2954 0 : : KSBA_SR_BEGIN_DATA;
2955 : }
2956 0 : else if (state == sDATAREADY)
2957 0 : stop_reason = KSBA_SR_NEED_SIG;
2958 0 : else if (state == sGOTSIG)
2959 0 : stop_reason = KSBA_SR_READY;
2960 :
2961 0 : cms->stop_reason = stop_reason;
2962 0 : return 0;
2963 : }
2964 :
2965 :
2966 : /* write everything up to the encryptedContentInfo including the tag */
2967 : static gpg_error_t
2968 0 : build_enveloped_data_header (ksba_cms_t cms)
2969 : {
2970 : gpg_error_t err;
2971 : int recpno;
2972 0 : ksba_asn_tree_t cms_tree = NULL;
2973 : struct certlist_s *certlist;
2974 : unsigned char *buf;
2975 : const char *s;
2976 : size_t len;
2977 0 : ksba_writer_t tmpwrt = NULL;
2978 :
2979 : /* Write the outer contentInfo */
2980 : /* fixme: code is shared with signed_data_header */
2981 0 : err = _ksba_ber_write_tl (cms->writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, 0);
2982 0 : if (err)
2983 0 : return err;
2984 0 : err = ksba_oid_from_str (cms->content.oid, &buf, &len);
2985 0 : if (err)
2986 0 : return err;
2987 0 : err = _ksba_ber_write_tl (cms->writer,
2988 : TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, len);
2989 0 : if (!err)
2990 0 : err = ksba_writer_write (cms->writer, buf, len);
2991 0 : xfree (buf);
2992 0 : if (err)
2993 0 : return err;
2994 :
2995 0 : err = _ksba_ber_write_tl (cms->writer, 0, CLASS_CONTEXT, 1, 0);
2996 0 : if (err)
2997 0 : return err;
2998 :
2999 : /* The SEQUENCE */
3000 0 : err = _ksba_ber_write_tl (cms->writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, 0);
3001 0 : if (err)
3002 0 : return err;
3003 :
3004 : /* figure out the CMSVersion to be used (from rfc2630):
3005 : version is the syntax version number. If originatorInfo is
3006 : present, then version shall be 2. If any of the RecipientInfo
3007 : structures included have a version other than 0, then the version
3008 : shall be 2. If unprotectedAttrs is present, then version shall
3009 : be 2. If originatorInfo is absent, all of the RecipientInfo
3010 : structures are version 0, and unprotectedAttrs is absent, then
3011 : version shall be 0.
3012 :
3013 : For SPHINX the version number must be 0.
3014 : */
3015 0 : s = "\x00";
3016 0 : err = _ksba_ber_write_tl (cms->writer, TYPE_INTEGER, CLASS_UNIVERSAL, 0, 1);
3017 0 : if (err)
3018 0 : return err;
3019 0 : err = ksba_writer_write (cms->writer, s, 1);
3020 0 : if (err)
3021 0 : return err;
3022 :
3023 : /* Note: originatorInfo is not yet implemented and must not be used
3024 : for SPHINX */
3025 :
3026 : /* Now we write the recipientInfo */
3027 0 : err = ksba_asn_create_tree ("cms", &cms_tree);
3028 0 : if (err)
3029 0 : return err;
3030 :
3031 0 : certlist = cms->cert_list;
3032 0 : if (!certlist)
3033 : {
3034 0 : err = gpg_error (GPG_ERR_MISSING_VALUE); /* oops */
3035 0 : goto leave;
3036 : }
3037 :
3038 : /* To construct the set we use a temporary writer object */
3039 0 : err = ksba_writer_new (&tmpwrt);
3040 0 : if (err)
3041 0 : goto leave;
3042 0 : err = ksba_writer_set_mem (tmpwrt, 2048);
3043 0 : if (err)
3044 0 : goto leave;
3045 :
3046 0 : for (recpno=0; certlist; recpno++, certlist = certlist->next)
3047 : {
3048 : AsnNode root, n;
3049 : unsigned char *image;
3050 : size_t imagelen;
3051 :
3052 0 : if (!certlist->cert)
3053 : {
3054 0 : err = gpg_error (GPG_ERR_BUG);
3055 0 : goto leave;
3056 : }
3057 :
3058 0 : root = _ksba_asn_expand_tree (cms_tree->parse_tree,
3059 : "CryptographicMessageSyntax.RecipientInfo");
3060 :
3061 : /* We store a version of 0 because we are only allowed to use
3062 : the issuerAndSerialNumber for SPHINX */
3063 0 : n = _ksba_asn_find_node (root, "RecipientInfo.ktri.version");
3064 0 : if (!n)
3065 : {
3066 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
3067 0 : goto leave;
3068 : }
3069 0 : err = _ksba_der_store_integer (n, "\x00\x00\x00\x01\x00");
3070 0 : if (err)
3071 0 : goto leave;
3072 :
3073 : /* Store the rid */
3074 0 : n = _ksba_asn_find_node (root, "RecipientInfo.ktri.rid");
3075 0 : if (!n)
3076 : {
3077 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
3078 0 : goto leave;
3079 : }
3080 :
3081 0 : err = set_issuer_serial (n, certlist->cert, 1);
3082 0 : if (err)
3083 0 : goto leave;
3084 :
3085 : /* store the keyEncryptionAlgorithm */
3086 0 : if (!certlist->enc_val.algo || !certlist->enc_val.value)
3087 0 : return gpg_error (GPG_ERR_MISSING_VALUE);
3088 0 : n = _ksba_asn_find_node (root,
3089 : "RecipientInfo.ktri.keyEncryptionAlgorithm.algorithm");
3090 0 : if (!n)
3091 : {
3092 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
3093 0 : goto leave;
3094 : }
3095 0 : err = _ksba_der_store_oid (n, certlist->enc_val.algo);
3096 0 : if (err)
3097 0 : goto leave;
3098 0 : n = _ksba_asn_find_node (root,
3099 : "RecipientInfo.ktri.keyEncryptionAlgorithm.parameters");
3100 0 : if (!n)
3101 : {
3102 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
3103 0 : goto leave;
3104 : }
3105 :
3106 : /* Now store NULL for the optional parameters. From Peter
3107 : * Gutmann's X.509 style guide:
3108 : *
3109 : * Another pitfall to be aware of is that algorithms which
3110 : * have no parameters have this specified as a NULL value
3111 : * rather than omitting the parameters field entirely. The
3112 : * reason for this is that when the 1988 syntax for
3113 : * AlgorithmIdentifier was translated into the 1997 syntax,
3114 : * the OPTIONAL associated with the AlgorithmIdentifier
3115 : * parameters got lost. Later it was recovered via a defect
3116 : * report, but by then everyone thought that algorithm
3117 : * parameters were mandatory. Because of this the algorithm
3118 : * parameters should be specified as NULL, regardless of what
3119 : * you read elsewhere.
3120 : *
3121 : * The trouble is that things *never* get better, they just
3122 : * stay the same, only more so
3123 : * -- Terry Pratchett, "Eric"
3124 : *
3125 : * Although this is about signing, we always do it. Versions of
3126 : * Libksba before 1.0.6 had a bug writing out the NULL tag here,
3127 : * thus in reality we used to be correct according to the
3128 : * standards despite we didn't intended so.
3129 : */
3130 :
3131 0 : err = _ksba_der_store_null (n);
3132 0 : if (err)
3133 0 : goto leave;
3134 :
3135 : /* store the encryptedKey */
3136 0 : if (!certlist->enc_val.value)
3137 : {
3138 0 : err = gpg_error (GPG_ERR_MISSING_VALUE);
3139 0 : goto leave;
3140 : }
3141 0 : n = _ksba_asn_find_node (root, "RecipientInfo.ktri.encryptedKey");
3142 0 : if (!n)
3143 : {
3144 0 : err = gpg_error (GPG_ERR_ELEMENT_NOT_FOUND);
3145 0 : goto leave;
3146 : }
3147 0 : err = _ksba_der_store_octet_string (n,
3148 0 : certlist->enc_val.value,
3149 : certlist->enc_val.valuelen);
3150 0 : if (err)
3151 0 : goto leave;
3152 :
3153 :
3154 : /* Make the DER encoding and write it out */
3155 0 : err = _ksba_der_encode_tree (root, &image, &imagelen);
3156 0 : if (err)
3157 0 : goto leave;
3158 :
3159 0 : err = ksba_writer_write (tmpwrt, image, imagelen);
3160 0 : if (err)
3161 0 : goto leave;
3162 :
3163 0 : xfree (image);
3164 0 : _ksba_asn_release_nodes (root);
3165 : }
3166 :
3167 0 : ksba_asn_tree_release (cms_tree);
3168 0 : cms_tree = NULL;
3169 :
3170 : /* Write out the SET filled with all recipient infos */
3171 : {
3172 : unsigned char *value;
3173 : size_t valuelen;
3174 :
3175 0 : value = ksba_writer_snatch_mem (tmpwrt, &valuelen);
3176 0 : if (!value)
3177 : {
3178 0 : err = gpg_error (GPG_ERR_ENOMEM);
3179 0 : goto leave;
3180 : }
3181 0 : ksba_writer_release (tmpwrt);
3182 0 : tmpwrt = NULL;
3183 0 : err = _ksba_ber_write_tl (cms->writer, TYPE_SET, CLASS_UNIVERSAL,
3184 : 1, valuelen);
3185 0 : if (!err)
3186 0 : err = ksba_writer_write (cms->writer, value, valuelen);
3187 0 : xfree (value);
3188 0 : if (err)
3189 0 : goto leave;
3190 : }
3191 :
3192 :
3193 : /* Write the (inner) encryptedContentInfo */
3194 0 : err = _ksba_ber_write_tl (cms->writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, 0);
3195 0 : if (err)
3196 0 : return err;
3197 0 : err = ksba_oid_from_str (cms->inner_cont_oid, &buf, &len);
3198 0 : if (err)
3199 0 : return err;
3200 0 : err = _ksba_ber_write_tl (cms->writer,
3201 : TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, len);
3202 0 : if (!err)
3203 0 : err = ksba_writer_write (cms->writer, buf, len);
3204 0 : xfree (buf);
3205 0 : if (err)
3206 0 : return err;
3207 :
3208 : /* and the encryptionAlgorithm */
3209 0 : err = _ksba_der_write_algorithm_identifier (cms->writer,
3210 0 : cms->encr_algo_oid,
3211 0 : cms->encr_iv,
3212 : cms->encr_ivlen);
3213 0 : if (err)
3214 0 : return err;
3215 :
3216 : /* write the tag for the encrypted data, it is an implicit octect
3217 : string in constructed form and indefinite length */
3218 0 : err = _ksba_ber_write_tl (cms->writer, 0, CLASS_CONTEXT, 1, 0);
3219 0 : if (err)
3220 0 : return err;
3221 :
3222 : /* Now the encrypted data should be written */
3223 :
3224 : leave:
3225 0 : ksba_writer_release (tmpwrt);
3226 0 : ksba_asn_tree_release (cms_tree);
3227 0 : return err;
3228 : }
3229 :
3230 :
3231 : static gpg_error_t
3232 0 : ct_build_enveloped_data (ksba_cms_t cms)
3233 : {
3234 : enum {
3235 : sSTART,
3236 : sINDATA,
3237 : sREST,
3238 : sERROR
3239 0 : } state = sERROR;
3240 : ksba_stop_reason_t stop_reason;
3241 0 : gpg_error_t err = 0;
3242 :
3243 0 : stop_reason = cms->stop_reason;
3244 0 : cms->stop_reason = KSBA_SR_RUNNING;
3245 :
3246 : /* Calculate state from last reason and do some checks */
3247 0 : if (stop_reason == KSBA_SR_GOT_CONTENT)
3248 0 : state = sSTART;
3249 0 : else if (stop_reason == KSBA_SR_BEGIN_DATA)
3250 0 : state = sINDATA;
3251 0 : else if (stop_reason == KSBA_SR_END_DATA)
3252 0 : state = sREST;
3253 0 : else if (stop_reason == KSBA_SR_RUNNING)
3254 0 : err = gpg_error (GPG_ERR_INV_STATE);
3255 0 : else if (stop_reason)
3256 0 : err = gpg_error (GPG_ERR_BUG);
3257 :
3258 0 : if (err)
3259 0 : return err;
3260 :
3261 : /* Do the action */
3262 0 : if (state == sSTART)
3263 0 : err = build_enveloped_data_header (cms);
3264 0 : else if (state == sINDATA)
3265 0 : err = write_encrypted_cont (cms);
3266 0 : else if (state == sREST)
3267 : {
3268 : /* SPHINX does not allow for unprotectedAttributes */
3269 :
3270 : /* Write 5 end tags */
3271 0 : err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
3272 0 : if (!err)
3273 0 : err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
3274 0 : if (!err)
3275 0 : err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
3276 0 : if (!err)
3277 0 : err = _ksba_ber_write_tl (cms->writer, 0, 0, 0, 0);
3278 : }
3279 : else
3280 0 : err = gpg_error (GPG_ERR_INV_STATE);
3281 :
3282 0 : if (err)
3283 0 : return err;
3284 :
3285 : /* Calculate new stop reason */
3286 0 : if (state == sSTART)
3287 : { /* user should now write the encrypted data */
3288 0 : stop_reason = KSBA_SR_BEGIN_DATA;
3289 : }
3290 0 : else if (state == sINDATA)
3291 : { /* tell the user that we wrote everything */
3292 0 : stop_reason = KSBA_SR_END_DATA;
3293 : }
3294 0 : else if (state == sREST)
3295 : {
3296 0 : stop_reason = KSBA_SR_READY;
3297 : }
3298 :
3299 0 : cms->stop_reason = stop_reason;
3300 0 : return 0;
3301 : }
3302 :
3303 :
3304 : static gpg_error_t
3305 0 : ct_build_digested_data (ksba_cms_t cms)
3306 : {
3307 : (void)cms;
3308 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
3309 : }
3310 :
3311 :
3312 : static gpg_error_t
3313 0 : ct_build_encrypted_data (ksba_cms_t cms)
3314 : {
3315 : (void)cms;
3316 0 : return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
3317 : }
|