libksba  1.6.0
About: KSBA is a library to make the tasks of working with X.509 certificates, CMS data and related objects more easy.
  Fossies Dox: libksba-1.6.0.tar.bz2  ("unofficial" and yet experimental doxygen-generated source code documentation)  

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