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)  

certreq.c
Go to the documentation of this file.
1 /* certreq.c - create pkcs-10 messages
2  * Copyright (C) 2002, 2011, 2012 g10 Code GmbH
3  *
4  * This file is part of KSBA.
5  *
6  * KSBA is free software; you can redistribute it and/or modify
7  * it under the terms of either
8  *
9  * - the GNU Lesser General Public License as published by the Free
10  * Software Foundation; either version 3 of the License, or (at
11  * your option) any later version.
12  *
13  * or
14  *
15  * - the GNU General Public License as published by the Free
16  * Software Foundation; either version 2 of the License, or (at
17  * your option) any later version.
18  *
19  * or both in parallel, as here.
20  *
21  * KSBA is distributed in the hope that it will be useful, but WITHOUT
22  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
24  * License for more details.
25  *
26  * You should have received a copies of the GNU General Public License
27  * and the GNU Lesser General Public License along with this program;
28  * if not, see <http://www.gnu.org/licenses/>.
29  */
30 
31 #include <config.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <assert.h>
36 #include <errno.h>
37 
38 #include "util.h"
39 
40 #include "cms.h"
41 #include "convert.h"
42 #include "keyinfo.h"
43 #include "der-encoder.h"
44 #include "ber-help.h"
45 #include "sexp-parse.h"
46 #include "certreq.h"
47 
48 static const char oidstr_subjectAltName[] = "2.5.29.17";
49 static const char oidstr_extensionReq[] = "1.2.840.113549.1.9.14";
50 
51 #if 0 /* Set to 1 to use this debug helper. */
52 static void
53 log_sexp (const char *text, ksba_const_sexp_t p)
54 {
55  int level = 0;
56 
57  gpgrt_log_debug ("%s: ", text);
58  if (!p)
59  gpgrt_log_printf ("[none]");
60  else
61  {
62  for (;;)
63  {
64  if (*p == '(')
65  {
66  gpgrt_log_printf ("%c", *p);
67  p++;
68  level++;
69  }
70  else if (*p == ')')
71  {
72  gpgrt_log_printf ("%c", *p);
73  p++;
74  if (--level <= 0 )
75  return;
76  }
77  else if (!digitp (p))
78  {
79  gpgrt_log_printf ("[invalid s-exp]");
80  return;
81  }
82  else
83  {
84  char *endp;
85  const unsigned char *s;
86  unsigned long len, n;
87 
88  len = strtoul (p, &endp, 10);
89  p = endp;
90  if (*p != ':')
91  {
92  gpgrt_log_printf ("[invalid s-exp]");
93  return;
94  }
95  p++;
96  for (s=p,n=0; n < len; n++, s++)
97  if ( !((*s >= 'a' && *s <= 'z')
98  || (*s >= 'A' && *s <= 'Z')
99  || (*s >= '0' && *s <= '9')
100  || *s == '-' || *s == '.'))
101  break;
102  if (n < len)
103  {
104  gpgrt_log_printf ("#");
105  for (n=0; n < len; n++, p++)
106  gpgrt_log_printf ("%02X", *p);
107  gpgrt_log_printf ("#");
108  }
109  else
110  {
111  for (n=0; n < len; n++, p++)
112  gpgrt_log_printf ("%c", *p);
113  }
114  }
115  }
116  }
117  gpgrt_log_printf ("\n");
118 }
119 #endif /* debug helper */
120 
121 ␌
122 /**
123  * ksba_cms_new:
124  *
125  * Create a new and empty CMS object
126  *
127  * Return value: A CMS object or an error code.
128  **/
129 gpg_error_t
131 {
132  *r_cr = xtrycalloc (1, sizeof **r_cr);
133  if (!*r_cr)
134  return gpg_error_from_errno (errno);
135 
136  return 0;
137 }
138 
139 /**
140  * ksba_certreq_release:
141  * @cms: A Certreq object
142  *
143  * Release a Certreq object.
144  **/
145 void
147 {
148  if (!cr)
149  return;
150  xfree (cr->x509.serial.der);
151  xfree (cr->x509.issuer.der);
152  xfree (cr->x509.siginfo.der);
153  xfree (cr->subject.der);
154  xfree (cr->key.der);
155  xfree (cr->cri.der);
156  xfree (cr->sig_val.algo);
157  xfree (cr->sig_val.value);
158  while (cr->subject_alt_names)
159  {
160  struct general_names_s *tmp = cr->subject_alt_names->next;
161  xfree (cr->subject_alt_names);
162  cr->subject_alt_names = tmp;
163  }
164  while (cr->extn_list)
165  {
166  struct extn_list_s *e = cr->extn_list->next;
167  xfree (cr->extn_list);
168  cr->extn_list = e;
169  }
170 
171  xfree (cr);
172 }
173 
174 
175 gpg_error_t
177 {
178  if (!cr || !w)
179  return gpg_error (GPG_ERR_INV_VALUE);
180  cr->writer = w;
181  return 0;
182 }
183 
184 
185 /* Provide a hash function so that we are able to hash the data */
186 void
188  void (*hash_fnc)(void *, const void *, size_t),
189  void *hash_fnc_arg)
190 {
191  if (cr)
192  {
193  cr->hash_fnc = hash_fnc;
194  cr->hash_fnc_arg = hash_fnc_arg;
195  }
196 }
197 
198 
199 ␌
200 /* Store the serial number. If this function is used, a real X.509
201  certificate will be built instead of a pkcs#10 certificate signing
202  request. SN must be a simple canonical encoded s-expression with
203  the serial number as its only item. Note that this function allows
204  to set a negative serial number, which is not forbidden but
205  probably not a good idea. */
206 gpg_error_t
208 {
209  const char *p = (const char *)sn;
210  unsigned long n;
211  char *endp;
212 
213  if (!cr || !sn || !p || *p != '(')
214  return gpg_error (GPG_ERR_INV_VALUE);
215 
216  p++;
217  n = strtoul (p, &endp, 10);
218  p = endp;
219  if (*p++ != ':' || !n)
220  return gpg_error (GPG_ERR_INV_VALUE);
221 
222  /* Remove invalid leading zero bytes. */
223  for (; n > 1 && !*p && !(p[1] & 0x80); n--, p++)
224  ;
225 
226  if (cr->x509.serial.der)
227  return gpg_error (GPG_ERR_CONFLICT); /* Already set */
228  cr->x509.serial.der = xtrymalloc (n);
229  if (!cr->x509.serial.der)
230  return gpg_error_from_syserror ();
231  memcpy (cr->x509.serial.der, p, n);
232  cr->x509.serial.derlen = n;
233 
234  return 0;
235 }
236 
237 
238 /* Store the issuer's name. NAME must be a valid RFC-2253 encoded DN
239  name. Only used for building an X.509 certificate. */
240 gpg_error_t
242 {
243  if (!cr || !name)
244  return gpg_error (GPG_ERR_INV_VALUE);
245  if (cr->x509.issuer.der)
246  return gpg_error (GPG_ERR_CONFLICT); /* Already set */
247  return _ksba_dn_from_str (name, &cr->x509.issuer.der,
248  &cr->x509.issuer.derlen);
249 }
250 
251 /* Store validity information. The time is in TIMEBUF. A value of 0
252  for WHAT stores the notBefore time, a value of 1 stores the
253  notAfter time. Only used for building an X.509 certificate. */
254 gpg_error_t
256  const ksba_isotime_t timebuf)
257 {
258  if (!cr || what < 0 || what > 1
259  || !timebuf || _ksba_assert_time_format (timebuf))
260  return gpg_error (GPG_ERR_INV_VALUE);
261 
262  _ksba_copy_time (what?cr->x509.not_after:cr->x509.not_before, timebuf);
263  return 0;
264 }
265 
266 
267 /* Store the signing key info. This is used to extract the signing
268  algorithm; the signing itself needs to be done by the caller as
269  response to a stop code. The expression SIGINFO is similar to a
270  sig-val one, however most parameters are not required. The
271  expected structure of this canonical encoded s-expression is:
272 
273  (sig-val
274  (<algo>
275  (<param_name1> <value>)
276  ...
277  (<param_namen> <value>)))
278 
279 */
280 gpg_error_t
282 {
283  if (!cr || !siginfo)
284  return gpg_error (GPG_ERR_INV_VALUE);
285  xfree (cr->x509.siginfo.der);
286  cr->x509.siginfo.der = NULL;
287 
288  return _ksba_keyinfo_from_sexp (siginfo, 1, &cr->x509.siginfo.der,
289  &cr->x509.siginfo.derlen);
290 }
291 
292 
293 ␌
294 /* Store the subject's name. Does perform some syntactic checks on
295  the name. The first added subject is the real one, all subsequent
296  calls add subjectAltNames.
297 
298  NAME must be a valid RFC-2253 encoded DN name for the first one or an
299  email address enclosed in angle brackets for all further calls.
300  */
301 gpg_error_t
303 {
304  unsigned long namelen;
305  size_t n, n1;
306  struct general_names_s *gn;
307  unsigned char *der;
308  int tag;
309  const char *endp;
310 
311  if (!cr || !name)
312  return gpg_error (GPG_ERR_INV_VALUE);
313  if (!cr->subject.der)
314  return _ksba_dn_from_str (name, &cr->subject.der, &cr->subject.derlen);
315  /* This is assumed to be an subjectAltName. */
316 
317  /* Note that the way we pass the name should match what
318  ksba_cert_get_subject() returns. In particular we expect that it
319  is a real string and thus a canonical S-expression is
320  additionally terminated by a 0. */
321  namelen = strlen (name);
322  if (*name == '<' && name[namelen-1] == '>'
323  && namelen >= 4 && strchr (name, '@'))
324  {
325  name++;
326  namelen -= 2;
327  tag = 1; /* rfc822Name */
328  }
329  else if (!strncmp (name, "(8:dns-name", 11))
330  {
331  tag = 2; /* dNSName */
332  namelen = strtoul (name+11, (char**)&endp, 10);
333  name = endp;
334  if (!namelen || *name != ':')
335  return gpg_error (GPG_ERR_INV_SEXP);
336  name++;
337  }
338  else if (!strncmp (name, "(3:uri", 6))
339  {
340  tag = 6; /* uRI */
341  namelen = strtoul (name+6, (char**)&endp, 10);
342  name = endp;
343  if (!namelen || *name != ':')
344  return gpg_error (GPG_ERR_INV_SEXP);
345  name++;
346  }
347  else
348  return gpg_error (GPG_ERR_INV_VALUE);
349 
350  n1 = _ksba_ber_count_tl (tag, CLASS_CONTEXT, 0, namelen);
351  n1 += namelen;
352 
353  gn = xtrymalloc (sizeof *gn + n1 - 1);
354  if (!gn)
355  return gpg_error_from_errno (errno);
356  gn->tag = tag;
357  gn->datalen = n1;
358  der = (unsigned char *)gn->data;
359  n = _ksba_ber_encode_tl (der, tag, CLASS_CONTEXT, 0, namelen);
360  if (!n)
361  return gpg_error (GPG_ERR_BUG);
362  der += n;
363  memcpy (der, name, namelen);
364  assert (der + namelen - (unsigned char*)gn->data == n1);
365 
366  gn->next = cr->subject_alt_names;
367  cr->subject_alt_names = gn;
368 
369  return 0;
370 }
371 
372 
373 /* Add the GeneralNames object GNAMES to the list of extensions in CR.
374  Use OID as object identifier for the extensions. */
375 static gpg_error_t
377  const char *oid)
378 {
379  struct general_names_s *g;
380  size_t n, n1, n2;
381  struct extn_list_s *e;
382  unsigned char *der;
383 
384  /* Calculate the required size. */
385  n1 = 0;
386  for (g=gnames; g; g = g->next)
387  n1 += g->datalen;
388 
390  n2 += n1;
391 
392  /* Allocate memory and encode all. */
393  e = xtrymalloc (sizeof *e + n2 - 1);
394  if (!e)
395  return gpg_error_from_errno (errno);
396  e->oid = oid;
397  e->critical = 0;
398  e->derlen = n2;
399  der = e->der;
401  if (!n)
402  return gpg_error (GPG_ERR_BUG); /* (no need to cleanup after a bug) */
403  der += n;
404 
405  for (g=gnames; g; g = g->next)
406  {
407  memcpy (der, g->data, g->datalen);
408  der += g->datalen;
409  }
410  assert (der - e->der == n2);
411 
412  e->next = cr->extn_list;
413  cr->extn_list = e;
414  return 0;
415 }
416 
417 /* Store the subject's publickey. */
418 gpg_error_t
420 {
421  if (!cr)
422  return gpg_error (GPG_ERR_INV_VALUE);
423 
424  xfree (cr->key.der);
425  cr->key.der = NULL;
426  return _ksba_keyinfo_from_sexp (key, 0, &cr->key.der, &cr->key.derlen);
427 }
428 
429 
430 /* Generic function to add an extension to a certificate request. The
431  extension must be provided readily encoded in the buffer DER of
432  length DERLEN bytes; the OID is to be given in OID and IS_CRIT
433  should be set to true if that extension shall be marked
434  critical. */
435 gpg_error_t
437  const char *oid, int is_crit,
438  const void *der, size_t derlen)
439 {
440  size_t oidlen;
441  struct extn_list_s *e;
442 
443  if (!cr || !oid|| !*oid || !der || !derlen)
444  return gpg_error (GPG_ERR_INV_VALUE);
445 
446  oidlen = strlen (oid);
447  e = xtrymalloc (sizeof *e + derlen + oidlen);
448  if (!e)
449  return gpg_error_from_errno (errno);
450  e->critical = is_crit;
451  e->derlen = derlen;
452  memcpy (e->der, der, derlen);
453  strcpy (e->der+derlen, oid);
454  e->oid = e->der + derlen;
455 
456  e->next = cr->extn_list;
457  cr->extn_list = e;
458 
459  return 0;
460 }
461 
462 
463 
464 ␌
465 /*
466  * r_sig = (sig-val
467  * (<algo>
468  * (<param_name1> <mpi>)
469  * ...
470  * (<param_namen> <mpi>)
471  * ))
472  * The sexp must be in canonical form.
473  * Fixme: The code is mostly duplicated from cms.c
474  * Note, that <algo> must be given as a stringified OID or the special
475  * string "rsa" which is translated to sha1WithRSAEncryption
476 */
477 gpg_error_t
479 {
480  const unsigned char *s, *saved;
481  char *buf = NULL;
482  unsigned long n, len;
483  int pass, nparam;
484 
485  if (!cr)
486  return gpg_error (GPG_ERR_INV_VALUE);
487 
488  s = sigval;
489  if (*s != '(')
490  return gpg_error (GPG_ERR_INV_SEXP);
491  s++;
492 
493  if (!(n = snext (&s)))
494  return gpg_error (GPG_ERR_INV_SEXP);
495  if (!smatch (&s, 7, "sig-val"))
496  return gpg_error (GPG_ERR_UNKNOWN_SEXP);
497  if (*s != '(')
498  return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
499  s++;
500 
501  /* break out the algorithm ID */
502  if (!(n = snext (&s)))
503  return gpg_error (GPG_ERR_INV_SEXP);
504  xfree (cr->sig_val.algo);
505  if (n==3 && s[0] == 'r' && s[1] == 's' && s[2] == 'a')
506  { /* kludge to allow "rsa" to be passed as algorithm name */
507  cr->sig_val.algo = xtrystrdup ("1.2.840.113549.1.1.5");
508  if (!cr->sig_val.algo)
509  return gpg_error (GPG_ERR_ENOMEM);
510  }
511  else
512  {
513  cr->sig_val.algo = xtrymalloc (n+1);
514  if (!cr->sig_val.algo)
515  return gpg_error (GPG_ERR_ENOMEM);
516  memcpy (cr->sig_val.algo, s, n);
517  cr->sig_val.algo[n] = 0;
518  if (!memcmp (s, "eddsa", 5))
519  cr->sig_val.is_ecc = 2;
520  }
521  s += n;
522 
523  if (cr->sig_val.is_ecc == 2
524  || !strcmp (cr->sig_val.algo, "1.3.101.112") /* Ed25519 */
525  || !strcmp (cr->sig_val.algo, "1.3.101.113")) /* Ed448 */
526  cr->sig_val.is_ecc = 2;
527  else if (!strcmp (cr->sig_val.algo, "1.2.840.10045.4.1") /* with-sha1 */
528  || !strcmp (cr->sig_val.algo, "1.2.840.10045.4.3.1") /* with-sha224 */
529  || !strcmp (cr->sig_val.algo, "1.2.840.10045.4.3.2") /* with-sha256 */
530  || !strcmp (cr->sig_val.algo, "1.2.840.10045.4.3.3") /* with-sha384 */
531  || !strcmp (cr->sig_val.algo, "1.2.840.10045.4.3.4"))/* with-sha512 */
532  cr->sig_val.is_ecc = 1;
533  else
534  cr->sig_val.is_ecc = 0;
535 
536  /* And now the values.
537  *
538  * If there is only one value, the signature is simply
539  * that value. Otherwise, the signature is a DER-encoded
540  * SEQUENCE of INTEGERs representing the different values.
541  *
542  * We need three passes over the values:
543  * - first pass is to get the number of values (nparam);
544  * - second pass is to compute the total length (len);
545  * - third pass is to build the final signature. */
546  for (pass = 1, nparam = len = 0, saved = s; pass < 4; pass++)
547  {
548  s = saved;
549 
550  if (pass == 3)
551  {
552  size_t needed = len;
553  if (cr->sig_val.is_ecc != 2 && nparam > 1)
555  1, len);
556 
557  xfree (cr->sig_val.value);
558  cr->sig_val.value = xtrymalloc (needed);
559  if (!cr->sig_val.value)
560  return gpg_error (GPG_ERR_ENOMEM);
561  cr->sig_val.valuelen = needed;
562  buf = cr->sig_val.value;
563 
564  if (cr->sig_val.is_ecc != 2 && nparam > 1)
565  buf += _ksba_ber_encode_tl (buf, TYPE_SEQUENCE,
566  CLASS_UNIVERSAL, 1, len);
567  }
568 
569  while (*s != ')')
570  {
571  if (*s != '(')
572  return gpg_error (digitp (s)? GPG_ERR_UNKNOWN_SEXP : GPG_ERR_INV_SEXP);
573  s++;
574  if (!(n = snext (&s)))
575  return gpg_error (GPG_ERR_INV_SEXP);
576  s += n; /* Ignore the name of the parameter. */
577 
578  if (!digitp (s))
579  return gpg_error (GPG_ERR_UNKNOWN_SEXP);
580  if (!(n = snext (&s)))
581  return gpg_error (GPG_ERR_INV_SEXP);
582 
583  if (pass == 1)
584  nparam++;
585  else if (pass == 2)
586  {
587  if (cr->sig_val.is_ecc == 2 || nparam == 1)
588  len += n;
589  else
591  *s >= 0x80? n + 1 : n)
592  + (*s >= 0x80? n + 1 : n);
593  }
594  else if (pass == 3)
595  {
596  if (cr->sig_val.is_ecc == 2 || nparam == 1)
597  {
598  memcpy (buf, s, n);
599  buf += n;
600  }
601  else
602  {
603  if (*s >= 0x80)
604  { /* Add leading zero byte. */
605  buf += _ksba_ber_encode_tl (buf, TYPE_INTEGER,
606  CLASS_UNIVERSAL, 0, n + 1);
607  *buf++ = 0;
608  }
609  else
610  buf += _ksba_ber_encode_tl (buf, TYPE_INTEGER,
611  CLASS_UNIVERSAL, 0, n);
612  memcpy (buf, s, n);
613  buf += n;
614  }
615  }
616 
617  s += n;
618  if (*s != ')')
619  return gpg_error (GPG_ERR_UNKNOWN_SEXP);
620  s++;
621  }
622  }
623 
624  /* we need 2 closing parenthesis */
625  if ( *s != ')' || s[1] != ')')
626  return gpg_error (GPG_ERR_INV_SEXP);
627 
628  return 0;
629 }
630 
631 
632 ␌
633 /* Build the extension block and return it in R_DER and R_DERLEN. IF
634  CERTMODE is true build X.509 certificate extension instead. */
635 static gpg_error_t
637  void **r_der, size_t *r_derlen)
638 {
639  gpg_error_t err;
640  ksba_writer_t writer, w=NULL;
641  struct extn_list_s *e;
642  unsigned char *value = NULL;
643  size_t valuelen;
644  unsigned char *p;
645  size_t n;
646 
647  *r_der = NULL;
648  *r_derlen = 0;
649  err = ksba_writer_new (&writer);
650  if (err)
651  goto leave;
652  err = ksba_writer_set_mem (writer, 2048);
653  if (err)
654  goto leave;
655  err = ksba_writer_new (&w);
656  if (err)
657  goto leave;
658 
659  for (e=cr->extn_list; e; e = e->next)
660  {
661  err = ksba_writer_set_mem (w, e->derlen + 100);
662  if (err)
663  goto leave;
664 
665  err = ksba_oid_from_str (e->oid, &p, &n);
666  if(err)
667  goto leave;
669  if (!err)
670  err = ksba_writer_write (w, p, n);
671  xfree (p);
672 
673  if (e->critical)
674  {
676  if (!err)
677  err = ksba_writer_write (w, "\xff", 1);
678  if(err)
679  goto leave;
680  }
681 
683  0, e->derlen);
684  if (!err)
685  err = ksba_writer_write (w, e->der, e->derlen);
686  if(err)
687  goto leave;
688 
689  p = ksba_writer_snatch_mem (w, &n);
690  if (!p)
691  {
692  err = gpg_error (GPG_ERR_ENOMEM);
693  goto leave;
694  }
696  1, n);
697  if (!err)
698  err = ksba_writer_write (writer, p, n);
699  xfree (p); p = NULL;
700  if (err)
701  goto leave;
702  }
703 
704  /* Embed all the sequences into another sequence */
705  value = ksba_writer_snatch_mem (writer, &valuelen);
706  if (!value)
707  {
708  err = gpg_error (GPG_ERR_ENOMEM);
709  goto leave;
710  }
711  err = ksba_writer_set_mem (writer, valuelen+10);
712  if (err)
713  goto leave;
715  1, valuelen);
716  if (!err)
717  err = ksba_writer_write (writer, value, valuelen);
718  if (err)
719  goto leave;
720 
721  xfree (value);
722  value = ksba_writer_snatch_mem (writer, &valuelen);
723  if (!value)
724  {
725  err = gpg_error (GPG_ERR_ENOMEM);
726  goto leave;
727  }
728 
729  if (!certmode)
730  {
731  /* Now create the extension request sequence content */
732  err = ksba_writer_set_mem (writer, valuelen+100);
733  if (err)
734  goto leave;
735  err = ksba_oid_from_str (oidstr_extensionReq, &p, &n);
736  if(err)
737  goto leave;
738  err = _ksba_ber_write_tl (writer, TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, n);
739  if (!err)
740  err = ksba_writer_write (writer, p, n);
741  xfree (p); p = NULL;
742  if (err)
743  return err;
744  err = _ksba_ber_write_tl (writer, TYPE_SET, CLASS_UNIVERSAL, 1, valuelen);
745  if (!err)
746  err = ksba_writer_write (writer, value, valuelen);
747 
748  /* Put this all into a SEQUENCE */
749  xfree (value);
750  value = ksba_writer_snatch_mem (writer, &valuelen);
751  if (!value)
752  {
753  err = gpg_error (GPG_ERR_ENOMEM);
754  goto leave;
755  }
756  err = ksba_writer_set_mem (writer, valuelen+10);
757  if (err)
758  goto leave;
760  1, valuelen);
761  if (!err)
762  err = ksba_writer_write (writer, value, valuelen);
763  if (err)
764  goto leave;
765 
766  xfree (value);
767  value = ksba_writer_snatch_mem (writer, &valuelen);
768  if (!value)
769  {
770  err = gpg_error (GPG_ERR_ENOMEM);
771  goto leave;
772  }
773  }
774 
775  *r_der = value;
776  *r_derlen = valuelen;
777  value = NULL;
778 
779 
780  leave:
781  ksba_writer_release (writer);
783  xfree (value);
784  return err;
785 }
786 
787 
788 /* Build a value tree from the already stored values. */
789 static gpg_error_t
791 {
792  gpg_error_t err;
793  ksba_writer_t writer;
794  void *value = NULL;
795  size_t valuelen;
796  int certmode;
797 
798  /* If a serial number has been set, we don't create a CSR but a
799  proper certificate. */
800  certmode = !!cr->x509.serial.der;
801 
802  err = ksba_writer_new (&writer);
803  if (err)
804  goto leave;
805  err = ksba_writer_set_mem (writer, 2048);
806  if (err)
807  goto leave;
808 
809  if (!cr->key.der)
810  {
811  err = gpg_error (GPG_ERR_MISSING_VALUE);
812  goto leave;
813  }
814 
815  /* We write all stuff out to a temporary writer object, then use
816  this object to create the cri and store the cri image */
817 
818  if (certmode)
819  {
820  /* Store the version structure; version is 3 (encoded as 2):
821  [0] { INTEGER 2 } */
822  err = ksba_writer_write (writer, "\xa0\x03\x02\x01\x02", 5);
823  }
824  else
825  {
826  /* Store version v1 (which is a 0). */
827  err = _ksba_ber_write_tl (writer, TYPE_INTEGER, CLASS_UNIVERSAL, 0, 1);
828  if (!err)
829  err = ksba_writer_write (writer, "", 1);
830  }
831  if (err)
832  goto leave;
833 
834  /* For a certificate we need to store the s/n, the signature
835  algorithm identifier, the issuer DN and the validity. */
836  if (certmode)
837  {
838  /* Store the serial number. */
840  cr->x509.serial.derlen);
841  if (!err)
842  err = ksba_writer_write (writer,
843  cr->x509.serial.der, cr->x509.serial.derlen);
844  if (err)
845  goto leave;
846 
847  /* Store the signature algorithm identifier. */
848  if (!cr->x509.siginfo.der)
849  err = gpg_error (GPG_ERR_MISSING_VALUE);
850  else
851  err = ksba_writer_write (writer,
852  cr->x509.siginfo.der, cr->x509.siginfo.derlen);
853  if (err)
854  goto leave;
855 
856 
857  /* Store the issuer DN. If no issuer DN has been set we use the
858  subject DN. */
859  if (cr->x509.issuer.der)
860  err = ksba_writer_write (writer,
861  cr->x509.issuer.der, cr->x509.issuer.derlen);
862  else if (cr->subject.der)
863  err = ksba_writer_write (writer, cr->subject.der, cr->subject.derlen);
864  else
865  err = gpg_error (GPG_ERR_MISSING_VALUE);
866  if (err)
867  goto leave;
868 
869  /* Store the Validity. */
870  {
871  unsigned char templ[36];
872  unsigned char *tp;
873 
874  tp = templ;
875  *tp++ = 0x30;
876  *tp++ = 0x22;
877 
878  *tp++ = TYPE_GENERALIZED_TIME;
879  *tp++ = 15;
880  if (cr->x509.not_before[0])
881  {
882  if (_ksba_cmp_time (cr->x509.not_before, "20500101T000000") >= 0)
883  {
884  memcpy (tp, cr->x509.not_before, 8);
885  tp += 8;
886  memcpy (tp, cr->x509.not_before+9, 6);
887  tp += 6;
888  }
889  else
890  {
891  tp[-2] = TYPE_UTC_TIME;
892  tp[-1] = 13;
893  memcpy (tp, cr->x509.not_before+2, 6);
894  tp += 6;
895  memcpy (tp, cr->x509.not_before+9, 6);
896  tp += 6;
897  }
898  }
899  else
900  {
901  tp[-2] = TYPE_UTC_TIME;
902  tp[-1] = 13;
903  memcpy (tp, "110101000000", 12);
904  tp += 12;
905  }
906  *tp++ = 'Z';
907 
908  *tp++ = TYPE_GENERALIZED_TIME;
909  *tp++ = 15;
910  if (cr->x509.not_after[0])
911  {
912  if (_ksba_cmp_time (cr->x509.not_after, "20500101T000000") >= 0)
913  {
914  memcpy (tp, cr->x509.not_after, 8);
915  tp += 8;
916  memcpy (tp, cr->x509.not_after+9, 6);
917  tp += 6;
918  }
919  else
920  {
921  tp[-2] = TYPE_UTC_TIME;
922  tp[-1] = 13;
923  memcpy (tp, cr->x509.not_after+2, 6);
924  tp += 6;
925  memcpy (tp, cr->x509.not_after+9, 6);
926  tp += 6;
927  }
928  }
929  else
930  {
931  memcpy (tp,"20630405170000", 14);
932  tp += 14;
933  }
934  *tp++ = 'Z';
935  assert (tp - templ <= 36);
936  templ[1] = tp - templ - 2; /* Fixup the sequence length. */
937 
938  err = ksba_writer_write (writer, templ, tp - templ);
939  if (err)
940  goto leave;
941  }
942  }
943 
944  /* store the subject */
945  if (!cr->subject.der)
946  {
947  err = gpg_error (GPG_ERR_MISSING_VALUE);
948  goto leave;
949  }
950  err = ksba_writer_write (writer, cr->subject.der, cr->subject.derlen);
951  if (err)
952  goto leave;
953 
954  /* store the public key info */
955  err = ksba_writer_write (writer, cr->key.der, cr->key.derlen);
956  if (err)
957  goto leave;
958 
959  /* Copy generalNames objects to the extension list. */
960  if (cr->subject_alt_names)
961  {
964  if (err)
965  goto leave;
966  while (cr->subject_alt_names)
967  {
968  struct general_names_s *tmp = cr->subject_alt_names->next;
969  xfree (cr->subject_alt_names);
970  cr->subject_alt_names = tmp;
971  }
972  cr->subject_alt_names = NULL;
973  }
974 
975 
976  /* Write the extensions. Note that the implicit SET OF is REQUIRED */
977  xfree (value); value = NULL;
978  valuelen = 0;
979  if (cr->extn_list)
980  {
981  err = build_extensions (cr, certmode, &value, &valuelen);
982  if (err)
983  goto leave;
984  err = _ksba_ber_write_tl (writer, certmode? 3:0,
985  CLASS_CONTEXT, 1, valuelen);
986  if (!err)
987  err = ksba_writer_write (writer, value, valuelen);
988  if (err)
989  goto leave;
990  }
991  else
992  { /* We can't write an object of length zero using our ber_write
993  function. So we must open encode it. */
994  err = ksba_writer_write (writer,
995  certmode? "\xa3\x02\x30":"\xa0\x02\x30", 4);
996  if (err)
997  goto leave;
998  }
999 
1000 
1001  /* pack it into the sequence */
1002  xfree (value);
1003  value = ksba_writer_snatch_mem (writer, &valuelen);
1004  if (!value)
1005  {
1006  err = gpg_error (GPG_ERR_ENOMEM);
1007  goto leave;
1008  }
1009  /* reinitialize the buffer to create the outer sequence */
1010  err = ksba_writer_set_mem (writer, valuelen+10);
1011  if (err)
1012  goto leave;
1013  /* write outer sequence */
1015  1, valuelen);
1016  if (!err)
1017  err = ksba_writer_write (writer, value, valuelen);
1018  if (err)
1019  goto leave;
1020 
1021  /* and store the final result */
1022  cr->cri.der = ksba_writer_snatch_mem (writer, &cr->cri.derlen);
1023  if (!cr->cri.der)
1024  err = gpg_error (GPG_ERR_ENOMEM);
1025 
1026  leave:
1027  ksba_writer_release (writer);
1028  xfree (value);
1029  return err;
1030 }
1031 
1032 static gpg_error_t
1034 {
1035  if (!cr->hash_fnc)
1036  return gpg_error (GPG_ERR_MISSING_ACTION);
1037  if (!cr->cri.der)
1038  return gpg_error (GPG_ERR_INV_STATE);
1039  cr->hash_fnc (cr->hash_fnc_arg, cr->cri.der, cr->cri.derlen);
1040  return 0;
1041 }
1042 
1043 
1044 /* The user has calculated the signatures and we can now write
1045  the signature */
1046 static gpg_error_t
1048 {
1049  gpg_error_t err;
1050  ksba_der_t dbld;
1051  unsigned char *value = NULL;
1052  size_t valuelen;
1053 
1054  dbld = _ksba_der_builder_new (0);
1055  if (!dbld)
1056  {
1057  err = gpg_error_from_syserror ();
1058  goto leave;
1059  }
1060 
1061  /* Start outer sequence. */
1062  _ksba_der_add_tag (dbld, 0, TYPE_SEQUENCE);
1063 
1064  /* Store the cri */
1065  if (!cr->cri.der)
1066  {
1067  err = gpg_error (GPG_ERR_MISSING_VALUE);
1068  goto leave;
1069  }
1070  _ksba_der_add_der (dbld, cr->cri.der, cr->cri.derlen);
1071 
1072  /* Store the signatureAlgorithm */
1073  if (!cr->sig_val.algo)
1074  return gpg_error (GPG_ERR_MISSING_VALUE);
1075  _ksba_der_add_tag (dbld, 0, TYPE_SEQUENCE);
1076  _ksba_der_add_oid (dbld, cr->sig_val.algo);
1077  if (!cr->sig_val.is_ecc)
1078  _ksba_der_add_ptr (dbld, 0, TYPE_NULL, NULL, 0);
1079  _ksba_der_add_end (dbld);
1080 
1081  /* Write the signature */
1082  _ksba_der_add_bts (dbld, cr->sig_val.value, cr->sig_val.valuelen, 0);
1083 
1084  /* End outer sequence. */
1085  _ksba_der_add_end (dbld);
1086 
1087  /* and finally write the result */
1088  err = _ksba_der_builder_get (dbld, &value, &valuelen);
1089  if (err)
1090  goto leave;
1091 
1092  if (!cr->writer)
1093  err = gpg_error (GPG_ERR_MISSING_ACTION);
1094  else
1095  err = ksba_writer_write (cr->writer, value, valuelen);
1096 
1097  leave:
1098  ksba_der_release (dbld);
1099  xfree (value);
1100  return err;
1101 }
1102 
1103 
1104 ␌
1105 /* The main function to build a certificate request. It is used in a
1106  * loop to allow for interaction between the function and the caller */
1107 gpg_error_t
1109 {
1110  enum {
1111  sSTART,
1112  sHASHING,
1113  sGOTSIG,
1114  sERROR
1115  } state = sERROR;
1116  gpg_error_t err = 0;
1117  ksba_stop_reason_t stop_reason;
1118 
1119  if (!cr || !r_stopreason)
1120  return gpg_error (GPG_ERR_INV_VALUE);
1121 
1122  if (!cr->any_build_done)
1123  { /* first time initialization of the stop reason */
1124  *r_stopreason = 0;
1125  cr->any_build_done = 1;
1126  }
1127 
1128  /* Calculate state from last reason */
1129  stop_reason = *r_stopreason;
1130  *r_stopreason = KSBA_SR_RUNNING;
1131  switch (stop_reason)
1132  {
1133  case 0:
1134  state = sSTART;
1135  break;
1136  case KSBA_SR_NEED_HASH:
1137  state = sHASHING;
1138  break;
1139  case KSBA_SR_NEED_SIG:
1140  if (!cr->sig_val.algo)
1141  err = gpg_error (GPG_ERR_MISSING_ACTION);
1142  else
1143  state = sGOTSIG;
1144  break;
1145  case KSBA_SR_RUNNING:
1146  err = gpg_error (GPG_ERR_INV_STATE);
1147  break;
1148  default:
1149  err = gpg_error (GPG_ERR_BUG);
1150  break;
1151  }
1152  if (err)
1153  return err;
1154 
1155  /* Do the action */
1156  switch (state)
1157  {
1158  case sSTART:
1159  err = build_cri (cr);
1160  break;
1161  case sHASHING:
1162  err = hash_cri (cr);
1163  break;
1164  case sGOTSIG:
1165  err = sign_and_write (cr);
1166  break;
1167  default:
1168  err = gpg_error (GPG_ERR_INV_STATE);
1169  break;
1170  }
1171  if (err)
1172  return err;
1173 
1174  /* Calculate new stop reason */
1175  switch (state)
1176  {
1177  case sSTART:
1178  stop_reason = KSBA_SR_NEED_HASH; /* caller should set the hash function*/
1179  break;
1180  case sHASHING:
1181  stop_reason = KSBA_SR_NEED_SIG;
1182  break;
1183  case sGOTSIG:
1184  stop_reason = KSBA_SR_READY;
1185  break;
1186  default:
1187  break;
1188  }
1189 
1190  *r_stopreason = stop_reason;
1191  return 0;
1192 }
@ TYPE_OCTET_STRING
@ TYPE_NULL
@ TYPE_GENERALIZED_TIME
@ TYPE_OBJECT_ID
@ TYPE_BOOLEAN
@ TYPE_INTEGER
@ TYPE_SEQUENCE
@ TYPE_SET
@ TYPE_UTC_TIME
@ CLASS_CONTEXT
@ CLASS_UNIVERSAL
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
size_t _ksba_ber_encode_tl(unsigned char *buffer, unsigned long tag, enum tag_class class, int constructed, unsigned long length)
Definition: ber-help.c:376
size_t _ksba_ber_count_tl(unsigned long tag, enum tag_class class, int constructed, unsigned long length)
Definition: ber-help.c:434
static gpg_error_t add_general_names_to_extn(ksba_certreq_t cr, struct general_names_s *gnames, const char *oid)
Definition: certreq.c:376
static const char oidstr_subjectAltName[]
Definition: certreq.c:48
static gpg_error_t build_cri(ksba_certreq_t cr)
Definition: certreq.c:790
static gpg_error_t sign_and_write(ksba_certreq_t cr)
Definition: certreq.c:1047
static gpg_error_t build_extensions(ksba_certreq_t cr, int certmode, void **r_der, size_t *r_derlen)
Definition: certreq.c:636
static const char oidstr_extensionReq[]
Definition: certreq.c:49
static gpg_error_t hash_cri(ksba_certreq_t cr)
Definition: certreq.c:1033
const char * oid
Definition: cms.c:71
gpg_error_t _ksba_dn_from_str(const char *string, char **rbuf, size_t *rlength)
Definition: dn.c:1054
gpg_error_t _ksba_assert_time_format(const ksba_isotime_t atime)
Definition: time.c:102
int _ksba_cmp_time(const ksba_isotime_t a, const ksba_isotime_t b)
Definition: time.c:145
void _ksba_copy_time(ksba_isotime_t d, const ksba_isotime_t s)
Definition: time.c:127
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_add_bts(ksba_der_t d, const void *value, size_t valuelen, unsigned int unusedbits)
Definition: der-builder.c:255
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
size_t oidlen
Definition: dn.c:55
const char * name
Definition: dn.c:47
#define gpg_error_from_syserror()
Definition: gen-help.h:88
#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_error(a)
Definition: gen-help.h:87
gpg_error_t _ksba_keyinfo_from_sexp(ksba_const_sexp_t sexp, int algoinfomode, unsigned char **r_der, size_t *r_derlen)
Definition: keyinfo.c:1088
const unsigned char * der
Definition: keyinfo.c:367
unsigned int derlen
Definition: keyinfo.c:366
gpg_error_t ksba_certreq_set_public_key(ksba_certreq_t cr, ksba_const_sexp_t key)
void ksba_certreq_set_hash_function(ksba_certreq_t cr, void(*hash_fnc)(void *, const void *, size_t), void *hash_fnc_arg)
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)
gpg_error_t ksba_certreq_set_issuer(ksba_certreq_t cr, const char *name)
gpg_error_t ksba_certreq_set_sig_val(ksba_certreq_t cr, ksba_const_sexp_t sigval)
void ksba_der_release(ksba_der_t d)
gpg_error_t ksba_certreq_new(ksba_certreq_t *r_cr)
ksba_stop_reason_t
Definition: ksba.h:138
@ KSBA_SR_RUNNING
Definition: ksba.h:140
@ KSBA_SR_NEED_HASH
Definition: ksba.h:142
@ KSBA_SR_NEED_SIG
Definition: ksba.h:146
@ 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_certreq_add_extension(ksba_certreq_t cr, const char *oid, int is_crit, const void *der, size_t derlen)
gpg_error_t ksba_writer_write(ksba_writer_t w, const void *buffer, size_t length)
char ksba_isotime_t[16]
Definition: ksba.h:212
gpg_error_t ksba_certreq_build(ksba_certreq_t cr, ksba_stop_reason_t *r_stopreason)
gpg_error_t ksba_certreq_set_writer(ksba_certreq_t cr, ksba_writer_t w)
gpg_error_t ksba_certreq_add_subject(ksba_certreq_t cr, const char *name)
void ksba_writer_release(ksba_writer_t w)
gpg_error_t ksba_certreq_set_siginfo(ksba_certreq_t cr, ksba_const_sexp_t siginfo)
const unsigned char * ksba_const_sexp_t
Definition: ksba.h:275
void ksba_certreq_release(ksba_certreq_t cr)
gpg_error_t ksba_certreq_set_validity(ksba_certreq_t cr, int what, const ksba_isotime_t timebuf)
gpg_error_t ksba_certreq_set_serial(ksba_certreq_t cr, ksba_const_sexp_t sn)
void * ksba_writer_snatch_mem(ksba_writer_t w, size_t *nbytes)
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
struct extn_list_s * next
Definition: certreq.h:43
const char * oid
Definition: certreq.h:44
int derlen
Definition: certreq.h:46
unsigned char der[1]
Definition: certreq.h:47
int critical
Definition: certreq.h:45
char data[1]
Definition: certreq.h:60
struct general_names_s * next
Definition: certreq.h:54
size_t datalen
Definition: certreq.h:59
unsigned char * value
Definition: certreq.h:115
struct ksba_certreq_s::@8 key
struct ksba_certreq_s::@6::@13 siginfo
char * algo
Definition: certreq.h:113
struct ksba_certreq_s::@6::@12 issuer
void(* hash_fnc)(void *, const void *, size_t)
Definition: certreq.h:70
struct ksba_certreq_s::@9 cri
struct ksba_certreq_s::@6::@11 serial
struct general_names_s * subject_alt_names
Definition: certreq.h:103
size_t derlen
Definition: certreq.h:79
struct extn_list_s * extn_list
Definition: certreq.h:105
struct ksba_certreq_s::@10 sig_val
int any_build_done
Definition: certreq.h:73
ksba_writer_t writer
Definition: certreq.h:68
struct ksba_certreq_s::@7 subject
void * hash_fnc_arg
Definition: certreq.h:71
char * der
Definition: certreq.h:77
ksba_isotime_t not_after
Definition: certreq.h:86
size_t valuelen
Definition: certreq.h:116
struct ksba_certreq_s::@6 x509
ksba_isotime_t not_before
Definition: certreq.h:85
#define xfree(a)
Definition: util.h:58
#define xtrystrdup(a)
Definition: util.h:57
#define digitp(p)
Definition: util.h:109
#define xtrycalloc(a, b)
Definition: util.h:55