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