Line data Source code
1 : /* crl.c - CRL parser
2 : * Copyright (C) 2002, 2004, 2005, 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 "convert.h"
41 : #include "keyinfo.h"
42 : #include "der-encoder.h"
43 : #include "ber-help.h"
44 : #include "ber-decoder.h"
45 : #include "crl.h"
46 :
47 :
48 : static const char oidstr_crlNumber[] = "2.5.29.20";
49 : static const char oidstr_crlReason[] = "2.5.29.21";
50 : static const char oidstr_issuingDistributionPoint[] = "2.5.29.28";
51 : static const char oidstr_certificateIssuer[] = "2.5.29.29";
52 : static const char oidstr_authorityKeyIdentifier[] = "2.5.29.35";
53 :
54 : /* We better buffer the hashing. */
55 : static inline void
56 63 : do_hash (ksba_crl_t crl, const void *buffer, size_t length)
57 : {
58 189 : while (length)
59 : {
60 63 : size_t n = length;
61 :
62 63 : if (crl->hashbuf.used + n > sizeof crl->hashbuf.buffer)
63 0 : n = sizeof crl->hashbuf.buffer - crl->hashbuf.used;
64 63 : memcpy (crl->hashbuf.buffer+crl->hashbuf.used, buffer, n);
65 63 : crl->hashbuf.used += n;
66 63 : if (crl->hashbuf.used == sizeof crl->hashbuf.buffer)
67 : {
68 0 : if (crl->hash_fnc)
69 0 : crl->hash_fnc (crl->hash_fnc_arg,
70 0 : crl->hashbuf.buffer, crl->hashbuf.used);
71 0 : crl->hashbuf.used = 0;
72 : }
73 63 : buffer = (const char *)buffer + n;
74 63 : length -= n;
75 : }
76 63 : }
77 :
78 : #define HASH(a,b) do_hash (crl, (a), (b))
79 :
80 :
81 :
82 : static void
83 0 : parse_skip (unsigned char const **buf, size_t *len, struct tag_info *ti)
84 : {
85 0 : if (ti->length)
86 : {
87 0 : assert (ti->length <= *len);
88 0 : *len -= ti->length;
89 0 : *buf += ti->length;
90 : }
91 0 : }
92 :
93 : static gpg_error_t
94 13 : parse_sequence (unsigned char const **buf, size_t *len, struct tag_info *ti)
95 : {
96 : gpg_error_t err;
97 :
98 13 : err = _ksba_ber_parse_tl (buf, len, ti);
99 13 : if (err)
100 : ;
101 26 : else if (!(ti->class == CLASS_UNIVERSAL && ti->tag == TYPE_SEQUENCE
102 13 : && ti->is_constructed) )
103 0 : err = gpg_error (GPG_ERR_INV_OBJ);
104 13 : else if (ti->length > *len)
105 0 : err = gpg_error (GPG_ERR_BAD_BER);
106 13 : return err;
107 : }
108 :
109 : static gpg_error_t
110 1 : parse_integer (unsigned char const **buf, size_t *len, struct tag_info *ti)
111 : {
112 : gpg_error_t err;
113 :
114 1 : err = _ksba_ber_parse_tl (buf, len, ti);
115 1 : if (err)
116 : ;
117 2 : else if (!(ti->class == CLASS_UNIVERSAL && ti->tag == TYPE_INTEGER
118 1 : && !ti->is_constructed) )
119 0 : err = gpg_error (GPG_ERR_INV_OBJ);
120 1 : else if (!ti->length)
121 0 : err = gpg_error (GPG_ERR_TOO_SHORT);
122 1 : else if (ti->length > *len)
123 0 : err = gpg_error (GPG_ERR_BAD_BER);
124 :
125 1 : return err;
126 : }
127 :
128 : static gpg_error_t
129 13 : parse_octet_string (unsigned char const **buf, size_t *len, struct tag_info *ti)
130 : {
131 : gpg_error_t err;
132 :
133 13 : err= _ksba_ber_parse_tl (buf, len, ti);
134 13 : if (err)
135 : ;
136 26 : else if (!(ti->class == CLASS_UNIVERSAL && ti->tag == TYPE_OCTET_STRING
137 13 : && !ti->is_constructed) )
138 0 : err = gpg_error (GPG_ERR_INV_OBJ);
139 13 : else if (!ti->length)
140 0 : err = gpg_error (GPG_ERR_TOO_SHORT);
141 13 : else if (ti->length > *len)
142 0 : err = gpg_error (GPG_ERR_BAD_BER);
143 :
144 13 : return err;
145 : }
146 :
147 : static gpg_error_t
148 13 : parse_object_id_into_str (unsigned char const **buf, size_t *len, char **oid)
149 : {
150 : struct tag_info ti;
151 : gpg_error_t err;
152 :
153 13 : *oid = NULL;
154 13 : err = _ksba_ber_parse_tl (buf, len, &ti);
155 13 : if (err)
156 : ;
157 26 : else if (!(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_OBJECT_ID
158 13 : && !ti.is_constructed) )
159 0 : err = gpg_error (GPG_ERR_INV_OBJ);
160 13 : else if (!ti.length)
161 0 : err = gpg_error (GPG_ERR_TOO_SHORT);
162 13 : else if (ti.length > *len)
163 0 : err = gpg_error (GPG_ERR_BAD_BER);
164 13 : else if (!(*oid = ksba_oid_to_str (*buf, ti.length)))
165 0 : err = gpg_error_from_errno (errno);
166 : else
167 : {
168 13 : *buf += ti.length;
169 13 : *len -= ti.length;
170 : }
171 13 : return err;
172 : }
173 :
174 :
175 :
176 :
177 : /**
178 : * ksba_crl_new:
179 : *
180 : * Create a new and empty CRL object
181 : *
182 : * Return value: A CRL object or an error code.
183 : **/
184 : gpg_error_t
185 1 : ksba_crl_new (ksba_crl_t *r_crl)
186 : {
187 1 : *r_crl = xtrycalloc (1, sizeof **r_crl);
188 1 : if (!*r_crl)
189 0 : return gpg_error_from_errno (errno);
190 1 : return 0;
191 : }
192 :
193 :
194 : /**
195 : * ksba_crl_release:
196 : * @crl: A CRL object
197 : *
198 : * Release a CRL object.
199 : **/
200 : void
201 1 : ksba_crl_release (ksba_crl_t crl)
202 : {
203 1 : if (!crl)
204 0 : return;
205 1 : xfree (crl->algo.oid);
206 1 : xfree (crl->algo.parm);
207 :
208 1 : _ksba_asn_release_nodes (crl->issuer.root);
209 1 : xfree (crl->issuer.image);
210 :
211 1 : xfree (crl->item.serial);
212 :
213 1 : xfree (crl->sigval);
214 5 : while (crl->extension_list)
215 : {
216 3 : crl_extn_t tmp = crl->extension_list->next;
217 3 : xfree (crl->extension_list->oid);
218 3 : xfree (crl->extension_list);
219 3 : crl->extension_list = tmp;
220 : }
221 :
222 1 : xfree (crl);
223 : }
224 :
225 :
226 : gpg_error_t
227 1 : ksba_crl_set_reader (ksba_crl_t crl, ksba_reader_t r)
228 : {
229 1 : if (!crl || !r)
230 0 : return gpg_error (GPG_ERR_INV_VALUE);
231 :
232 1 : crl->reader = r;
233 1 : return 0;
234 : }
235 :
236 : /* Provide a hash function so that we are able to hash the data */
237 : void
238 0 : ksba_crl_set_hash_function (ksba_crl_t crl,
239 : void (*hash_fnc)(void *, const void *, size_t),
240 : void *hash_fnc_arg)
241 : {
242 0 : if (crl)
243 : {
244 0 : crl->hash_fnc = hash_fnc;
245 0 : crl->hash_fnc_arg = hash_fnc_arg;
246 : }
247 0 : }
248 :
249 :
250 :
251 : /*
252 : access functions
253 : */
254 :
255 :
256 : /**
257 : * ksba_crl_get_digest_algo:
258 : * @cms: CMS object
259 : *
260 : * Figure out the the digest algorithm used for the signature and return
261 : * its OID.
262 : *
263 : * Return value: NULL if the signature algorithm is not yet available
264 : * or there is a mismatched between "tbsCertList.signature" and
265 : * "signatureAlgorithm"; on success the OID is returned which is valid
266 : * as long as the CRL object is valid.
267 : **/
268 : const char *
269 2 : ksba_crl_get_digest_algo (ksba_crl_t crl)
270 : {
271 2 : if (!crl)
272 0 : return NULL;
273 :
274 : /* fixme: implement the described check */
275 :
276 2 : return crl->algo.oid;
277 : }
278 :
279 :
280 : /**
281 : * ksba_crl_get_issuer:
282 : * @cms: CMS object
283 : * @r_issuer: returns the issuer
284 : *
285 : * This functions returns the issuer of the CRL. The caller must
286 : * release the returned object.
287 : *
288 : * Return value: 0 on success or an error code
289 : **/
290 : gpg_error_t
291 1 : ksba_crl_get_issuer (ksba_crl_t crl, char **r_issuer)
292 : {
293 : gpg_error_t err;
294 : AsnNode n;
295 : const unsigned char *image;
296 :
297 1 : if (!crl || !r_issuer)
298 0 : return gpg_error (GPG_ERR_INV_VALUE);
299 1 : if (!crl->issuer.root)
300 0 : return gpg_error (GPG_ERR_NO_DATA);
301 :
302 1 : n = crl->issuer.root;
303 1 : image = crl->issuer.image;
304 :
305 1 : if (!n || !n->down)
306 0 : return gpg_error (GPG_ERR_NO_VALUE);
307 1 : n = n->down; /* dereference the choice node */
308 :
309 1 : if (n->off == -1)
310 : {
311 : /* fputs ("get_issuer problem at node:\n", stderr); */
312 : /* _ksba_asn_node_dump_all (n, stderr); */
313 0 : return gpg_error (GPG_ERR_GENERAL);
314 : }
315 1 : err = _ksba_dn_to_str (image, n, r_issuer);
316 :
317 1 : return err;
318 : }
319 :
320 :
321 : /* Return the CRL extension in OID, CRITICAL, DER and DERLEN. The
322 : caller should iterate IDX from 0 upwards until GPG_ERR_EOF is
323 : returned. Note, that the returned values are valid as long as the
324 : context is valid and no new parsing has been started. */
325 : gpg_error_t
326 4 : ksba_crl_get_extension (ksba_crl_t crl, int idx,
327 : char const **oid, int *critical,
328 : unsigned char const **der, size_t *derlen)
329 : {
330 : crl_extn_t e;
331 :
332 4 : if (!crl)
333 0 : return gpg_error (GPG_ERR_INV_VALUE);
334 4 : if (idx < 0)
335 0 : return gpg_error (GPG_ERR_INV_INDEX);
336 :
337 4 : for (e=crl->extension_list; e && idx; e = e->next, idx-- )
338 : ;
339 4 : if (!e)
340 1 : return gpg_error (GPG_ERR_EOF);
341 :
342 3 : if (oid)
343 3 : *oid = e->oid;
344 3 : if (critical)
345 3 : *critical = e->critical;
346 3 : if (der)
347 0 : *der = e->der;
348 3 : if (derlen)
349 3 : *derlen = e->derlen;
350 :
351 3 : return 0;
352 : }
353 :
354 :
355 : /* Return the authorityKeyIdentifier in r_name and r_serial or in
356 : r_keyID. GPG_ERR_NO_DATA is returned if no authorityKeyIdentifier
357 : or only one using the keyIdentifier method is available and R_KEYID
358 : is NULL.
359 :
360 : FIXME: This function shares a lot of code with the one in cert.c
361 : */
362 : gpg_error_t
363 1 : ksba_crl_get_auth_key_id (ksba_crl_t crl,
364 : ksba_sexp_t *r_keyid,
365 : ksba_name_t *r_name,
366 : ksba_sexp_t *r_serial)
367 : {
368 : gpg_error_t err;
369 : size_t derlen;
370 : const unsigned char *der;
371 1 : const unsigned char *keyid_der = NULL;
372 1 : size_t keyid_derlen = 0;
373 : struct tag_info ti;
374 : char numbuf[30];
375 : size_t numbuflen;
376 : crl_extn_t e;
377 :
378 1 : if (r_keyid)
379 1 : *r_keyid = NULL;
380 1 : if (!crl || !r_name || !r_serial)
381 0 : return gpg_error (GPG_ERR_INV_VALUE);
382 1 : *r_name = NULL;
383 1 : *r_serial = NULL;
384 :
385 2 : for (e=crl->extension_list; e; e = e->next)
386 2 : if (!strcmp (e->oid, oidstr_authorityKeyIdentifier))
387 1 : break;
388 1 : if (!e)
389 0 : return gpg_error (GPG_ERR_NO_DATA); /* not available */
390 :
391 : /* Check that there is only one */
392 : {
393 : crl_extn_t e2;
394 :
395 2 : for (e2 = e->next; e2; e2 = e2->next)
396 1 : if (!strcmp (e2->oid, oidstr_authorityKeyIdentifier))
397 0 : return gpg_error (GPG_ERR_DUP_VALUE);
398 : }
399 :
400 1 : der = e->der;
401 1 : derlen = e->derlen;
402 :
403 1 : err = _ksba_ber_parse_tl (&der, &derlen, &ti);
404 1 : if (err)
405 0 : return err;
406 2 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
407 1 : && ti.is_constructed) )
408 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
409 1 : if (ti.ndef)
410 0 : return gpg_error (GPG_ERR_NOT_DER_ENCODED);
411 1 : if (ti.length > derlen)
412 0 : return gpg_error (GPG_ERR_BAD_BER);
413 :
414 1 : err = _ksba_ber_parse_tl (&der, &derlen, &ti);
415 1 : if (err)
416 0 : return err;
417 1 : if (ti.class != CLASS_CONTEXT)
418 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ); /* We expected a tag. */
419 1 : if (ti.ndef)
420 0 : return gpg_error (GPG_ERR_NOT_DER_ENCODED);
421 1 : if (derlen < ti.length)
422 0 : return gpg_error (GPG_ERR_BAD_BER);
423 :
424 1 : if (ti.tag == 0)
425 : { /* keyIdentifier: Just save it away for later use. */
426 0 : keyid_der = der;
427 0 : keyid_derlen = ti.length;
428 :
429 0 : der += ti.length;
430 0 : derlen -= ti.length;
431 : /* If the keyid has been requested but no other data follows, we
432 : directly jump to the end. */
433 0 : if (r_keyid && !derlen)
434 0 : goto build_keyid;
435 0 : if (!derlen)
436 0 : return gpg_error (GPG_ERR_NO_DATA); /* not available */
437 :
438 0 : err = _ksba_ber_parse_tl (&der, &derlen, &ti);
439 0 : if (err)
440 0 : return err;
441 0 : if (ti.class != CLASS_CONTEXT)
442 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ); /* we expected a tag */
443 0 : if (ti.ndef)
444 0 : return gpg_error (GPG_ERR_NOT_DER_ENCODED);
445 0 : if (derlen < ti.length)
446 0 : return gpg_error (GPG_ERR_BAD_BER);
447 : }
448 :
449 1 : if (ti.tag != 1 || !derlen)
450 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
451 :
452 1 : err = _ksba_name_new_from_der (r_name, der, ti.length);
453 1 : if (err)
454 0 : return err;
455 :
456 1 : der += ti.length;
457 1 : derlen -= ti.length;
458 :
459 : /* Fixme: we should release r_name before returning on error */
460 1 : err = _ksba_ber_parse_tl (&der, &derlen, &ti);
461 1 : if (err)
462 0 : return err;
463 1 : if (ti.class != CLASS_CONTEXT)
464 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ); /* we expected a tag */
465 1 : if (ti.ndef)
466 0 : return gpg_error (GPG_ERR_NOT_DER_ENCODED);
467 1 : if (derlen < ti.length)
468 0 : return gpg_error (GPG_ERR_BAD_BER);
469 :
470 1 : if (ti.tag != 2 || !derlen)
471 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
472 :
473 1 : sprintf (numbuf,"(%u:", (unsigned int)ti.length);
474 1 : numbuflen = strlen (numbuf);
475 1 : *r_serial = xtrymalloc (numbuflen + ti.length + 2);
476 1 : if (!*r_serial)
477 0 : return gpg_error_from_errno (errno);
478 1 : strcpy (*r_serial, numbuf);
479 1 : memcpy (*r_serial+numbuflen, der, ti.length);
480 1 : (*r_serial)[numbuflen + ti.length] = ')';
481 1 : (*r_serial)[numbuflen + ti.length + 1] = 0;
482 :
483 : build_keyid:
484 1 : if (r_keyid && keyid_der && keyid_derlen)
485 : {
486 0 : sprintf (numbuf,"(%u:", (unsigned int)keyid_derlen);
487 0 : numbuflen = strlen (numbuf);
488 0 : *r_keyid = xtrymalloc (numbuflen + keyid_derlen + 2);
489 0 : if (!*r_keyid)
490 0 : return gpg_error (GPG_ERR_ENOMEM);
491 0 : strcpy (*r_keyid, numbuf);
492 0 : memcpy (*r_keyid+numbuflen, keyid_der, keyid_derlen);
493 0 : (*r_keyid)[numbuflen + keyid_derlen] = ')';
494 0 : (*r_keyid)[numbuflen + keyid_derlen + 1] = 0;
495 : }
496 1 : return 0;
497 : }
498 :
499 :
500 : /* Return the optional crlNumber in NUMBER or GPG_ERR_NO_DATA if it is
501 : not available. Caller must release NUMBER if the fuction retruned
502 : with success. */
503 : gpg_error_t
504 1 : ksba_crl_get_crl_number (ksba_crl_t crl, ksba_sexp_t *number)
505 : {
506 : gpg_error_t err;
507 : size_t derlen;
508 : const unsigned char *der;
509 : struct tag_info ti;
510 : char numbuf[30];
511 : size_t numbuflen;
512 : crl_extn_t e;
513 :
514 1 : if (!crl || !number)
515 0 : return gpg_error (GPG_ERR_INV_VALUE);
516 1 : *number = NULL;
517 :
518 3 : for (e=crl->extension_list; e; e = e->next)
519 3 : if (!strcmp (e->oid, oidstr_crlNumber))
520 1 : break;
521 1 : if (!e)
522 0 : return gpg_error (GPG_ERR_NO_DATA); /* not available */
523 :
524 : /* Check that there is only one. */
525 : {
526 : crl_extn_t e2;
527 :
528 1 : for (e2 = e->next; e2; e2 = e2->next)
529 0 : if (!strcmp (e2->oid, oidstr_crlNumber))
530 0 : return gpg_error (GPG_ERR_DUP_VALUE);
531 : }
532 :
533 1 : der = e->der;
534 1 : derlen = e->derlen;
535 :
536 1 : err = parse_integer (&der, &derlen, &ti);
537 1 : if (err)
538 0 : return err;
539 :
540 1 : sprintf (numbuf,"(%u:", (unsigned int)ti.length);
541 1 : numbuflen = strlen (numbuf);
542 1 : *number = xtrymalloc (numbuflen + ti.length + 2);
543 1 : if (!*number)
544 0 : return gpg_error_from_errno (errno);
545 1 : strcpy (*number, numbuf);
546 1 : memcpy (*number+numbuflen, der, ti.length);
547 1 : (*number)[numbuflen + ti.length] = ')';
548 1 : (*number)[numbuflen + ti.length + 1] = 0;
549 :
550 1 : return 0;
551 : }
552 :
553 :
554 :
555 :
556 : /**
557 : * ksba_crl_get_update_times:
558 : * @crl: CRL object
559 : * @this: Returns the thisUpdate value
560 : * @next: Returns the nextUpdate value.
561 : *
562 : * THIS and NEXT may be given as NULL if the value is not required.
563 : * Return value: 0 on success or an error code
564 : **/
565 : gpg_error_t
566 1 : ksba_crl_get_update_times (ksba_crl_t crl,
567 : ksba_isotime_t this,
568 : ksba_isotime_t next)
569 : {
570 1 : if (this)
571 1 : *this = 0;
572 1 : if (next)
573 1 : *next = 0;
574 1 : if (!crl)
575 0 : return gpg_error (GPG_ERR_INV_VALUE);
576 1 : if (!*crl->this_update)
577 0 : return gpg_error (GPG_ERR_INV_TIME);
578 1 : if (this)
579 1 : _ksba_copy_time (this, crl->this_update);
580 1 : if (next)
581 1 : _ksba_copy_time (next, crl->next_update);
582 1 : return 0;
583 : }
584 :
585 : /**
586 : * ksba_crl_get_item:
587 : * @crl: CRL object
588 : * @r_serial: Returns a S-exp with the serial number; caller must free.
589 : * @r_revocation_date: Returns the recocation date
590 : * @r_reason: Return the reason for revocation
591 : *
592 : * Return the serial number, revocation time and reason of the current
593 : * item. Any of these arguments may be passed as %NULL if the value
594 : * is not of interest. This function should be used after the parse
595 : * function came back with %KSBA_SR_GOT_ITEM. For efficiency reasons
596 : * the function should be called only once, the implementation may
597 : * return an error for the second call.
598 : *
599 : * Return value: 0 in success or an error code.
600 : **/
601 : gpg_error_t
602 10 : ksba_crl_get_item (ksba_crl_t crl, ksba_sexp_t *r_serial,
603 : ksba_isotime_t r_revocation_date,
604 : ksba_crl_reason_t *r_reason)
605 : {
606 10 : if (r_revocation_date)
607 10 : *r_revocation_date = 0;
608 :
609 10 : if (!crl)
610 0 : return gpg_error (GPG_ERR_INV_VALUE);
611 :
612 10 : if (r_serial)
613 : {
614 10 : if (!crl->item.serial)
615 0 : return gpg_error (GPG_ERR_NO_DATA);
616 10 : *r_serial = crl->item.serial;
617 10 : crl->item.serial = NULL;
618 : }
619 10 : if (r_revocation_date)
620 10 : _ksba_copy_time (r_revocation_date, crl->item.revocation_date);
621 10 : if (r_reason)
622 10 : *r_reason = crl->item.reason;
623 10 : return 0;
624 : }
625 :
626 :
627 :
628 : /**
629 : * ksba_crl_get_sig_val:
630 : * @crl: CRL object
631 : *
632 : * Return the actual signature in a format suitable to be used as
633 : * input to Libgcrypt's verification function. The caller must free
634 : * the returned string.
635 : *
636 : * Return value: NULL or a string with an S-Exp.
637 : **/
638 : ksba_sexp_t
639 1 : ksba_crl_get_sig_val (ksba_crl_t crl)
640 : {
641 : ksba_sexp_t p;
642 :
643 1 : if (!crl)
644 0 : return NULL;
645 :
646 1 : if (!crl->sigval)
647 0 : return NULL;
648 :
649 1 : p = crl->sigval;
650 1 : crl->sigval = NULL;
651 1 : return p;
652 : }
653 :
654 :
655 :
656 : /*
657 : Parser functions
658 : */
659 :
660 : /* read one byte */
661 : static int
662 1 : read_byte (ksba_reader_t reader)
663 : {
664 : unsigned char buf;
665 : size_t nread;
666 : int rc;
667 :
668 : do
669 1 : rc = ksba_reader_read (reader, &buf, 1, &nread);
670 1 : while (!rc && !nread);
671 1 : return rc? -1: buf;
672 : }
673 :
674 : /* read COUNT bytes into buffer. Return 0 on success */
675 : static int
676 38 : read_buffer (ksba_reader_t reader, char *buffer, size_t count)
677 : {
678 : size_t nread;
679 :
680 114 : while (count)
681 : {
682 38 : if (ksba_reader_read (reader, buffer, count, &nread))
683 0 : return -1;
684 38 : buffer += nread;
685 38 : count -= nread;
686 : }
687 38 : return 0;
688 : }
689 :
690 : /* Create a new decoder and run it for the given element */
691 : /* Fixme: this code is duplicated from cms-parser.c */
692 : static gpg_error_t
693 1 : create_and_run_decoder (ksba_reader_t reader, const char *elem_name,
694 : AsnNode *r_root,
695 : unsigned char **r_image, size_t *r_imagelen)
696 : {
697 : gpg_error_t err;
698 : ksba_asn_tree_t crl_tree;
699 : BerDecoder decoder;
700 :
701 1 : err = ksba_asn_create_tree ("tmttv2", &crl_tree);
702 1 : if (err)
703 0 : return err;
704 :
705 1 : decoder = _ksba_ber_decoder_new ();
706 1 : if (!decoder)
707 : {
708 0 : ksba_asn_tree_release (crl_tree);
709 0 : return gpg_error (GPG_ERR_ENOMEM);
710 : }
711 :
712 1 : err = _ksba_ber_decoder_set_reader (decoder, reader);
713 1 : if (err)
714 : {
715 0 : ksba_asn_tree_release (crl_tree);
716 0 : _ksba_ber_decoder_release (decoder);
717 0 : return err;
718 : }
719 :
720 1 : err = _ksba_ber_decoder_set_module (decoder, crl_tree);
721 1 : if (err)
722 : {
723 0 : ksba_asn_tree_release (crl_tree);
724 0 : _ksba_ber_decoder_release (decoder);
725 0 : return err;
726 : }
727 :
728 1 : err = _ksba_ber_decoder_decode (decoder, elem_name, 0,
729 : r_root, r_image, r_imagelen);
730 :
731 1 : _ksba_ber_decoder_release (decoder);
732 1 : ksba_asn_tree_release (crl_tree);
733 1 : return err;
734 : }
735 :
736 :
737 : /* Parse the extension in the buffer DER or length DERLEN and return
738 : the result in OID, CRITICAL, OFF and LEN. */
739 : static gpg_error_t
740 13 : parse_one_extension (const unsigned char *der, size_t derlen,
741 : char **oid, int *critical, size_t *off, size_t *len)
742 : {
743 : gpg_error_t err;
744 : struct tag_info ti;
745 13 : const unsigned char *start = der;
746 :
747 13 : *oid = NULL;
748 13 : *critical = 0;
749 13 : *off = *len = 0;
750 :
751 : /*
752 : Extension ::= SEQUENCE {
753 : extnID OBJECT IDENTIFIER,
754 : critical BOOLEAN DEFAULT FALSE,
755 : extnValue OCTET STRING }
756 : */
757 13 : err = parse_sequence (&der, &derlen, &ti);
758 13 : if (err)
759 0 : goto failure;
760 :
761 13 : err = parse_object_id_into_str (&der, &derlen, oid);
762 13 : if (err)
763 0 : goto failure;
764 :
765 13 : err = _ksba_ber_parse_tl (&der, &derlen, &ti);
766 13 : if (err)
767 0 : goto failure;
768 13 : if (ti.length > derlen)
769 0 : return gpg_error (GPG_ERR_BAD_BER);
770 13 : if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_BOOLEAN
771 0 : && !ti.is_constructed)
772 : {
773 0 : if (ti.length != 1)
774 0 : goto bad_ber;
775 0 : *critical = !!*der;
776 0 : parse_skip (&der, &derlen, &ti);
777 : }
778 : else
779 : { /* Undo that read. */
780 13 : der -= ti.nhdr;
781 13 : derlen += ti.nhdr;
782 : }
783 :
784 13 : err = parse_octet_string (&der, &derlen, &ti);
785 13 : if (err)
786 0 : goto failure;
787 13 : *off = der - start;
788 13 : *len = ti.length;
789 :
790 13 : return 0;
791 :
792 : bad_ber:
793 0 : err = gpg_error (GPG_ERR_BAD_BER);
794 : failure:
795 0 : xfree (*oid);
796 0 : *oid = NULL;
797 0 : return err;
798 : }
799 :
800 :
801 : /* Store an extension into the context. */
802 : static gpg_error_t
803 3 : store_one_extension (ksba_crl_t crl, const unsigned char *der, size_t derlen)
804 : {
805 : gpg_error_t err;
806 : char *oid;
807 : int critical;
808 : size_t off, len;
809 : crl_extn_t e;
810 :
811 3 : err = parse_one_extension (der, derlen, &oid, &critical, &off, &len);
812 3 : if (err)
813 0 : return err;
814 3 : e = xtrymalloc (sizeof *e + len - 1);
815 3 : if (!e)
816 : {
817 0 : err = gpg_error_from_errno (errno);
818 0 : xfree (oid);
819 0 : return err;
820 : }
821 3 : e->oid = oid;
822 3 : e->critical = critical;
823 3 : e->derlen = len;
824 3 : memcpy (e->der, der + off, len);
825 3 : e->next = crl->extension_list;
826 3 : crl->extension_list = e;
827 :
828 3 : return 0;
829 : }
830 :
831 :
832 :
833 : /* Parse the fixed block at the beginning. We use a custom parser
834 : here because our BER decoder is not yet able to stop at certain
835 : points */
836 : static gpg_error_t
837 1 : parse_to_next_update (ksba_crl_t crl)
838 : {
839 : gpg_error_t err;
840 : struct tag_info ti;
841 : unsigned long outer_len, tbs_len;
842 : int outer_ndef, tbs_ndef;
843 : int c;
844 : unsigned char tmpbuf[500]; /* for OID or algorithmIdentifier */
845 : size_t nread;
846 :
847 : /* read the outer sequence */
848 1 : err = _ksba_ber_read_tl (crl->reader, &ti);
849 1 : if (err)
850 0 : return err;
851 2 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
852 1 : && ti.is_constructed) )
853 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
854 1 : outer_len = ti.length;
855 1 : outer_ndef = ti.ndef;
856 1 : if (!outer_ndef && outer_len < 10)
857 0 : return gpg_error (GPG_ERR_TOO_SHORT);
858 :
859 : /* read the tbs sequence */
860 1 : err = _ksba_ber_read_tl (crl->reader, &ti);
861 1 : if (err)
862 0 : return err;
863 2 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
864 1 : && ti.is_constructed) )
865 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
866 1 : HASH (ti.buf, ti.nhdr);
867 1 : if (!outer_ndef)
868 : {
869 1 : if (outer_len < ti.nhdr)
870 0 : return gpg_error (GPG_ERR_BAD_BER); /* Triplet header larger
871 : than outer sequence */
872 1 : outer_len -= ti.nhdr;
873 1 : if (!ti.ndef && outer_len < ti.length)
874 0 : return gpg_error (GPG_ERR_BAD_BER); /* Triplet larger than
875 : outer sequence */
876 1 : outer_len -= ti.length;
877 : }
878 1 : tbs_len = ti.length;
879 1 : tbs_ndef = ti.ndef;
880 1 : if (!tbs_ndef && tbs_len < 10)
881 0 : return gpg_error (GPG_ERR_TOO_SHORT);
882 :
883 : /* read the optional version integer */
884 1 : crl->crl_version = -1;
885 1 : err = _ksba_ber_read_tl (crl->reader, &ti);
886 1 : if (err)
887 0 : return err;
888 1 : if ( ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_INTEGER)
889 : {
890 1 : if ( ti.is_constructed || !ti.length )
891 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
892 1 : HASH (ti.buf, ti.nhdr);
893 1 : if (!tbs_ndef)
894 : {
895 1 : if (tbs_len < ti.nhdr)
896 0 : return gpg_error (GPG_ERR_BAD_BER);
897 1 : tbs_len -= ti.nhdr;
898 1 : if (tbs_len < ti.length)
899 0 : return gpg_error (GPG_ERR_BAD_BER);
900 1 : tbs_len -= ti.length;
901 : }
902 : /* fixme: we should also check the outer data length here and in
903 : the follwing code. It might however be easier to to thsi at
904 : the end of this sequence */
905 1 : if (ti.length != 1)
906 0 : return gpg_error (GPG_ERR_UNSUPPORTED_CRL_VERSION);
907 1 : if ( (c=read_byte (crl->reader)) == -1)
908 : {
909 0 : err = ksba_reader_error (crl->reader);
910 0 : return err? err : gpg_error (GPG_ERR_GENERAL);
911 : }
912 1 : if ( !(c == 0 || c == 1) )
913 0 : return gpg_error (GPG_ERR_UNSUPPORTED_CRL_VERSION);
914 : {
915 1 : unsigned char tmp = c;
916 1 : HASH (&tmp, 1);
917 : }
918 1 : crl->crl_version = c;
919 1 : err = _ksba_ber_read_tl (crl->reader, &ti);
920 1 : if (err)
921 0 : return err;
922 : }
923 :
924 : /* read the algorithm identifier */
925 2 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
926 1 : && ti.is_constructed) )
927 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
928 1 : if (!tbs_ndef)
929 : {
930 1 : if (tbs_len < ti.nhdr)
931 0 : return gpg_error (GPG_ERR_BAD_BER);
932 1 : tbs_len -= ti.nhdr;
933 1 : if (!ti.ndef && tbs_len < ti.length)
934 0 : return gpg_error (GPG_ERR_BAD_BER);
935 1 : tbs_len -= ti.length;
936 : }
937 1 : if (ti.nhdr + ti.length >= DIM(tmpbuf))
938 0 : return gpg_error (GPG_ERR_TOO_LARGE);
939 1 : memcpy (tmpbuf, ti.buf, ti.nhdr);
940 1 : err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
941 1 : if (err)
942 0 : return err;
943 1 : HASH (tmpbuf, ti.nhdr+ti.length);
944 :
945 1 : xfree (crl->algo.oid); crl->algo.oid = NULL;
946 1 : xfree (crl->algo.parm); crl->algo.parm = NULL;
947 1 : err = _ksba_parse_algorithm_identifier2 (tmpbuf, ti.nhdr+ti.length, &nread,
948 : &crl->algo.oid,
949 : &crl->algo.parm,
950 : &crl->algo.parmlen);
951 1 : if (err)
952 0 : return err;
953 1 : assert (nread <= ti.nhdr + ti.length);
954 1 : if (nread < ti.nhdr + ti.length)
955 0 : return gpg_error (GPG_ERR_TOO_SHORT);
956 :
957 :
958 : /* read the name */
959 : {
960 1 : unsigned long n = ksba_reader_tell (crl->reader);
961 1 : err = create_and_run_decoder (crl->reader,
962 : "TMTTv2.CertificateList.tbsCertList.issuer",
963 : &crl->issuer.root,
964 : &crl->issuer.image,
965 : &crl->issuer.imagelen);
966 1 : if (err)
967 0 : return err;
968 : /* imagelen might be larger than the valid data (due to read ahead).
969 : So we need to get the count from the reader */
970 1 : n = ksba_reader_tell (crl->reader) - n;
971 1 : if (n > crl->issuer.imagelen)
972 0 : return gpg_error (GPG_ERR_BUG);
973 1 : HASH (crl->issuer.image, n);
974 :
975 1 : if (!tbs_ndef)
976 : {
977 1 : if (tbs_len < n)
978 0 : return gpg_error (GPG_ERR_BAD_BER);
979 1 : tbs_len -= n;
980 : }
981 : }
982 :
983 :
984 :
985 : /* read the thisUpdate time */
986 1 : err = _ksba_ber_read_tl (crl->reader, &ti);
987 1 : if (err)
988 0 : return err;
989 2 : if ( !(ti.class == CLASS_UNIVERSAL
990 1 : && (ti.tag == TYPE_UTC_TIME || ti.tag == TYPE_GENERALIZED_TIME)
991 1 : && !ti.is_constructed) )
992 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
993 1 : if (!tbs_ndef)
994 : {
995 1 : if (tbs_len < ti.nhdr)
996 0 : return gpg_error (GPG_ERR_BAD_BER);
997 1 : tbs_len -= ti.nhdr;
998 1 : if (!ti.ndef && tbs_len < ti.length)
999 0 : return gpg_error (GPG_ERR_BAD_BER);
1000 1 : tbs_len -= ti.length;
1001 : }
1002 1 : if (ti.nhdr + ti.length >= DIM(tmpbuf))
1003 0 : return gpg_error (GPG_ERR_TOO_LARGE);
1004 1 : memcpy (tmpbuf, ti.buf, ti.nhdr);
1005 1 : err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
1006 1 : if (err)
1007 0 : return err;
1008 1 : HASH (tmpbuf, ti.nhdr+ti.length);
1009 1 : _ksba_asntime_to_iso (tmpbuf+ti.nhdr, ti.length,
1010 1 : ti.tag == TYPE_UTC_TIME, crl->this_update);
1011 :
1012 : /* Read the optional nextUpdate time. */
1013 1 : err = _ksba_ber_read_tl (crl->reader, &ti);
1014 1 : if (err)
1015 0 : return err;
1016 1 : if ( ti.class == CLASS_UNIVERSAL
1017 1 : && (ti.tag == TYPE_UTC_TIME || ti.tag == TYPE_GENERALIZED_TIME)
1018 1 : && !ti.is_constructed )
1019 : {
1020 1 : if (!tbs_ndef)
1021 : {
1022 1 : if (tbs_len < ti.nhdr)
1023 0 : return gpg_error (GPG_ERR_BAD_BER);
1024 1 : tbs_len -= ti.nhdr;
1025 1 : if (!ti.ndef && tbs_len < ti.length)
1026 0 : return gpg_error (GPG_ERR_BAD_BER);
1027 1 : tbs_len -= ti.length;
1028 : }
1029 1 : if (ti.nhdr + ti.length >= DIM(tmpbuf))
1030 0 : return gpg_error (GPG_ERR_TOO_LARGE);
1031 1 : memcpy (tmpbuf, ti.buf, ti.nhdr);
1032 1 : err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
1033 1 : if (err)
1034 0 : return err;
1035 1 : HASH (tmpbuf, ti.nhdr+ti.length);
1036 1 : _ksba_asntime_to_iso (tmpbuf+ti.nhdr, ti.length,
1037 1 : ti.tag == TYPE_UTC_TIME, crl->next_update);
1038 1 : err = _ksba_ber_read_tl (crl->reader, &ti);
1039 1 : if (err)
1040 0 : return err;
1041 : }
1042 :
1043 : /* Read the first sequence tag of the optional SEQ of SEQ. */
1044 1 : if (tbs_ndef || tbs_len)
1045 : {
1046 1 : if (ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
1047 1 : && ti.is_constructed )
1048 : { /* yes, there is one */
1049 1 : HASH (ti.buf, ti.nhdr);
1050 1 : if (!tbs_ndef)
1051 : {
1052 1 : if (tbs_len < ti.nhdr)
1053 0 : return gpg_error (GPG_ERR_BAD_BER);
1054 1 : tbs_len -= ti.nhdr;
1055 1 : if (!ti.ndef && tbs_len < ti.length)
1056 0 : return gpg_error (GPG_ERR_BAD_BER);
1057 1 : tbs_len -= ti.length;
1058 : }
1059 1 : crl->state.have_seqseq = 1;
1060 1 : crl->state.seqseq_ndef = ti.ndef;
1061 1 : crl->state.seqseq_len = ti.length;
1062 : /* and read the next */
1063 1 : err = _ksba_ber_read_tl (crl->reader, &ti);
1064 1 : if (err)
1065 0 : return err;
1066 : }
1067 : }
1068 :
1069 : /* We need to save some stuff for the next round. */
1070 1 : crl->state.ti = ti;
1071 1 : crl->state.outer_ndef = outer_ndef;
1072 1 : crl->state.outer_len = outer_len;
1073 1 : crl->state.tbs_ndef = tbs_ndef;
1074 1 : crl->state.tbs_len = tbs_len;
1075 :
1076 1 : return 0;
1077 : }
1078 :
1079 :
1080 : /* Parse an enumerated value. Note that this code is duplication of
1081 : the one at ocsp.c. */
1082 : static gpg_error_t
1083 10 : parse_enumerated (unsigned char const **buf, size_t *len, struct tag_info *ti,
1084 : size_t maxlen)
1085 : {
1086 : gpg_error_t err;
1087 :
1088 10 : err = _ksba_ber_parse_tl (buf, len, ti);
1089 10 : if (err)
1090 : ;
1091 20 : else if (!(ti->class == CLASS_UNIVERSAL && ti->tag == TYPE_ENUMERATED
1092 10 : && !ti->is_constructed) )
1093 0 : err = gpg_error (GPG_ERR_INV_OBJ);
1094 10 : else if (!ti->length)
1095 0 : err = gpg_error (GPG_ERR_TOO_SHORT);
1096 10 : else if (maxlen && ti->length > maxlen)
1097 0 : err = gpg_error (GPG_ERR_TOO_LARGE);
1098 10 : else if (ti->length > *len)
1099 0 : err = gpg_error (GPG_ERR_BAD_BER);
1100 :
1101 10 : return err;
1102 : }
1103 :
1104 :
1105 :
1106 : /* Store an entry extension into the current item. */
1107 : static gpg_error_t
1108 10 : store_one_entry_extension (ksba_crl_t crl,
1109 : const unsigned char *der, size_t derlen)
1110 : {
1111 : gpg_error_t err;
1112 : char *oid;
1113 : int critical;
1114 : size_t off, len;
1115 :
1116 10 : err = parse_one_extension (der, derlen, &oid, &critical, &off, &len);
1117 10 : if (err)
1118 0 : return err;
1119 10 : if (!strcmp (oid, oidstr_crlReason))
1120 : {
1121 : struct tag_info ti;
1122 10 : const unsigned char *buf = der+off;
1123 10 : size_t mylen = len;
1124 :
1125 10 : err = parse_enumerated (&buf, &mylen, &ti, 1);
1126 10 : if (err)
1127 0 : return err;
1128 : /* Note that we OR the values so that in case this extension is
1129 : repeated we can track all reason codes. */
1130 10 : switch (*buf)
1131 : {
1132 2 : case 0: crl->item.reason |= KSBA_CRLREASON_UNSPECIFIED; break;
1133 0 : case 1: crl->item.reason |= KSBA_CRLREASON_KEY_COMPROMISE; break;
1134 0 : case 2: crl->item.reason |= KSBA_CRLREASON_CA_COMPROMISE; break;
1135 8 : case 3: crl->item.reason |= KSBA_CRLREASON_AFFILIATION_CHANGED; break;
1136 0 : case 4: crl->item.reason |= KSBA_CRLREASON_SUPERSEDED; break;
1137 0 : case 5: crl->item.reason |= KSBA_CRLREASON_CESSATION_OF_OPERATION;
1138 0 : break;
1139 0 : case 6: crl->item.reason |= KSBA_CRLREASON_CERTIFICATE_HOLD; break;
1140 0 : case 8: crl->item.reason |= KSBA_CRLREASON_REMOVE_FROM_CRL; break;
1141 0 : case 9: crl->item.reason |= KSBA_CRLREASON_PRIVILEGE_WITHDRAWN; break;
1142 0 : case 10: crl->item.reason |= KSBA_CRLREASON_AA_COMPROMISE; break;
1143 0 : default: crl->item.reason |= KSBA_CRLREASON_OTHER; break;
1144 : }
1145 : }
1146 10 : if (!strcmp (oid, oidstr_certificateIssuer))
1147 : {
1148 : /* FIXME: We need to implement this. */
1149 : }
1150 10 : else if (critical)
1151 0 : err = gpg_error (GPG_ERR_UNKNOWN_CRIT_EXTN);
1152 :
1153 10 : xfree (oid);
1154 :
1155 10 : return err;
1156 : }
1157 :
1158 : /* Parse the revokedCertificates SEQUENCE of SEQUENCE using a custom
1159 : parser for efficiency and return after each entry */
1160 : static gpg_error_t
1161 11 : parse_crl_entry (ksba_crl_t crl, int *got_entry)
1162 : {
1163 : gpg_error_t err;
1164 11 : struct tag_info ti = crl->state.ti;
1165 11 : unsigned long seqseq_len= crl->state.seqseq_len;
1166 11 : int seqseq_ndef = crl->state.seqseq_ndef;
1167 : unsigned long len;
1168 : int ndef;
1169 : unsigned char tmpbuf[4096]; /* for time, serial number and extensions */
1170 : char numbuf[22];
1171 : int numbuflen;
1172 :
1173 : /* Check the length to see whether we are at the end of the seq but do
1174 : this only when we know that we have this optional seq of seq. */
1175 11 : if (!crl->state.have_seqseq)
1176 0 : return 0; /* ready (no entries at all) */
1177 :
1178 11 : if (!seqseq_ndef && !seqseq_len)
1179 1 : return 0; /* ready */
1180 :
1181 : /* if this is not a SEQUENCE the CRL is invalid */
1182 20 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
1183 10 : && ti.is_constructed) )
1184 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
1185 10 : HASH (ti.buf, ti.nhdr);
1186 10 : if (!seqseq_ndef)
1187 : {
1188 10 : if (seqseq_len < ti.nhdr)
1189 0 : return gpg_error (GPG_ERR_BAD_BER);
1190 10 : seqseq_len -= ti.nhdr;
1191 10 : if (!ti.ndef && seqseq_len < ti.length)
1192 0 : return gpg_error (GPG_ERR_BAD_BER);
1193 10 : seqseq_len -= ti.length;
1194 : }
1195 10 : ndef = ti.ndef;
1196 10 : len = ti.length;
1197 :
1198 : /* get the serial number */
1199 10 : err = _ksba_ber_read_tl (crl->reader, &ti);
1200 10 : if (err)
1201 0 : return err;
1202 20 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_INTEGER
1203 10 : && !ti.is_constructed) )
1204 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
1205 10 : if (!ndef)
1206 : {
1207 10 : if (len < ti.nhdr)
1208 0 : return gpg_error (GPG_ERR_BAD_BER);
1209 10 : len -= ti.nhdr;
1210 10 : if (!ti.ndef && len < ti.length)
1211 0 : return gpg_error (GPG_ERR_BAD_BER);
1212 10 : len -= ti.length;
1213 : }
1214 10 : if (ti.nhdr + ti.length >= DIM(tmpbuf))
1215 0 : return gpg_error (GPG_ERR_TOO_LARGE);
1216 10 : memcpy (tmpbuf, ti.buf, ti.nhdr);
1217 10 : err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
1218 10 : if (err)
1219 0 : return err;
1220 10 : HASH (tmpbuf, ti.nhdr+ti.length);
1221 :
1222 10 : xfree (crl->item.serial);
1223 10 : sprintf (numbuf,"(%u:", (unsigned int)ti.length);
1224 10 : numbuflen = strlen (numbuf);
1225 10 : crl->item.serial = xtrymalloc (numbuflen + ti.length + 2);
1226 10 : if (!crl->item.serial)
1227 0 : return gpg_error (GPG_ERR_ENOMEM);
1228 10 : strcpy (crl->item.serial, numbuf);
1229 10 : memcpy (crl->item.serial+numbuflen, tmpbuf+ti.nhdr, ti.length);
1230 10 : crl->item.serial[numbuflen + ti.length] = ')';
1231 10 : crl->item.serial[numbuflen + ti.length + 1] = 0;
1232 10 : crl->item.reason = 0;
1233 :
1234 : /* get the revocation time */
1235 10 : err = _ksba_ber_read_tl (crl->reader, &ti);
1236 10 : if (err)
1237 0 : return err;
1238 20 : if ( !(ti.class == CLASS_UNIVERSAL
1239 10 : && (ti.tag == TYPE_UTC_TIME || ti.tag == TYPE_GENERALIZED_TIME)
1240 10 : && !ti.is_constructed) )
1241 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
1242 10 : if (!ndef)
1243 : {
1244 10 : if (len < ti.nhdr)
1245 0 : return gpg_error (GPG_ERR_BAD_BER);
1246 10 : len -= ti.nhdr;
1247 10 : if (!ti.ndef && len < ti.length)
1248 0 : return gpg_error (GPG_ERR_BAD_BER);
1249 10 : len -= ti.length;
1250 : }
1251 10 : if (ti.nhdr + ti.length >= DIM(tmpbuf))
1252 0 : return gpg_error (GPG_ERR_TOO_LARGE);
1253 10 : memcpy (tmpbuf, ti.buf, ti.nhdr);
1254 10 : err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
1255 10 : if (err)
1256 0 : return err;
1257 10 : HASH (tmpbuf, ti.nhdr+ti.length);
1258 :
1259 10 : _ksba_asntime_to_iso (tmpbuf+ti.nhdr, ti.length,
1260 10 : ti.tag == TYPE_UTC_TIME, crl->item.revocation_date);
1261 :
1262 : /* if there is still space we must parse the optional entryExtensions */
1263 10 : if (ndef)
1264 0 : return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1265 10 : else if (len)
1266 : {
1267 : /* read the outer sequence */
1268 10 : err = _ksba_ber_read_tl (crl->reader, &ti);
1269 10 : if (err)
1270 0 : return err;
1271 20 : if ( !(ti.class == CLASS_UNIVERSAL
1272 10 : && ti.tag == TYPE_SEQUENCE && ti.is_constructed) )
1273 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
1274 10 : if (ti.ndef)
1275 0 : return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1276 10 : HASH (ti.buf, ti.nhdr);
1277 10 : if (len < ti.nhdr)
1278 0 : return gpg_error (GPG_ERR_BAD_BER);
1279 10 : len -= ti.nhdr;
1280 10 : if (len < ti.length)
1281 0 : return gpg_error (GPG_ERR_BAD_BER);
1282 :
1283 : /* now loop over the extensions */
1284 30 : while (len)
1285 : {
1286 10 : err = _ksba_ber_read_tl (crl->reader, &ti);
1287 10 : if (err)
1288 0 : return err;
1289 20 : if ( !(ti.class == CLASS_UNIVERSAL
1290 10 : && ti.tag == TYPE_SEQUENCE && ti.is_constructed) )
1291 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
1292 10 : if (ti.ndef)
1293 0 : return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1294 10 : if (len < ti.nhdr)
1295 0 : return gpg_error (GPG_ERR_BAD_BER);
1296 10 : len -= ti.nhdr;
1297 10 : if (len < ti.length)
1298 0 : return gpg_error (GPG_ERR_BAD_BER);
1299 10 : len -= ti.length;
1300 10 : if (ti.nhdr + ti.length >= DIM(tmpbuf))
1301 0 : return gpg_error (GPG_ERR_TOO_LARGE);
1302 10 : memcpy (tmpbuf, ti.buf, ti.nhdr);
1303 10 : err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
1304 10 : if (err)
1305 0 : return err;
1306 10 : HASH (tmpbuf, ti.nhdr+ti.length);
1307 10 : err = store_one_entry_extension (crl, tmpbuf, ti.nhdr+ti.length);
1308 10 : if (err)
1309 0 : return err;
1310 : }
1311 : }
1312 :
1313 : /* read ahead */
1314 10 : err = _ksba_ber_read_tl (crl->reader, &ti);
1315 10 : if (err)
1316 0 : return err;
1317 :
1318 10 : *got_entry = 1;
1319 :
1320 : /* Fixme: the seqseq length is not correct if any element was ndef'd */
1321 10 : crl->state.ti = ti;
1322 10 : crl->state.seqseq_ndef = seqseq_ndef;
1323 10 : crl->state.seqseq_len = seqseq_len;
1324 :
1325 10 : return 0;
1326 : }
1327 :
1328 :
1329 : /* This function is used when a [0] tag was encountered to read the
1330 : crlExtensions */
1331 : static gpg_error_t
1332 1 : parse_crl_extensions (ksba_crl_t crl)
1333 : {
1334 : gpg_error_t err;
1335 1 : struct tag_info ti = crl->state.ti;
1336 : unsigned long ext_len, len;
1337 : unsigned char tmpbuf[4096]; /* for extensions */
1338 :
1339 : /* if we do not have a tag [0] we are done with this */
1340 1 : if (!(ti.class == CLASS_CONTEXT && ti.tag == 0 && ti.is_constructed))
1341 0 : return 0;
1342 1 : if (ti.ndef)
1343 0 : return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1344 1 : HASH (ti.buf, ti.nhdr);
1345 1 : ext_len = ti.length;
1346 :
1347 : /* read the outer sequence */
1348 1 : err = _ksba_ber_read_tl (crl->reader, &ti);
1349 1 : if (err)
1350 0 : return err;
1351 2 : if ( !(ti.class == CLASS_UNIVERSAL
1352 1 : && ti.tag == TYPE_SEQUENCE && ti.is_constructed) )
1353 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
1354 1 : if (ti.ndef)
1355 0 : return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1356 1 : HASH (ti.buf, ti.nhdr);
1357 1 : if (ext_len < ti.nhdr)
1358 0 : return gpg_error (GPG_ERR_BAD_BER);
1359 1 : ext_len -= ti.nhdr;
1360 1 : if (ext_len < ti.length)
1361 0 : return gpg_error (GPG_ERR_BAD_BER);
1362 1 : len = ti.length;
1363 :
1364 : /* now loop over the extensions */
1365 5 : while (len)
1366 : {
1367 3 : err = _ksba_ber_read_tl (crl->reader, &ti);
1368 3 : if (err)
1369 0 : return err;
1370 6 : if ( !(ti.class == CLASS_UNIVERSAL
1371 3 : && ti.tag == TYPE_SEQUENCE && ti.is_constructed) )
1372 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
1373 3 : if (ti.ndef)
1374 0 : return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1375 3 : if (len < ti.nhdr)
1376 0 : return gpg_error (GPG_ERR_BAD_BER);
1377 3 : len -= ti.nhdr;
1378 3 : if (len < ti.length)
1379 0 : return gpg_error (GPG_ERR_BAD_BER);
1380 3 : len -= ti.length;
1381 3 : if (ti.nhdr + ti.length >= DIM(tmpbuf))
1382 0 : return gpg_error (GPG_ERR_TOO_LARGE);
1383 : /* fixme use a larger buffer if the extension does not fit into tmpbuf */
1384 3 : memcpy (tmpbuf, ti.buf, ti.nhdr);
1385 3 : err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
1386 3 : if (err)
1387 0 : return err;
1388 3 : HASH (tmpbuf, ti.nhdr+ti.length);
1389 3 : err = store_one_extension (crl, tmpbuf, ti.nhdr+ti.length);
1390 3 : if (err)
1391 0 : return err;
1392 : }
1393 :
1394 : /* read ahead */
1395 1 : err = _ksba_ber_read_tl (crl->reader, &ti);
1396 1 : if (err)
1397 0 : return err;
1398 :
1399 1 : crl->state.ti = ti;
1400 1 : return 0;
1401 : }
1402 :
1403 : /* Parse the signatureAlgorithm and the signature */
1404 : static gpg_error_t
1405 1 : parse_signature (ksba_crl_t crl)
1406 : {
1407 : gpg_error_t err;
1408 1 : struct tag_info ti = crl->state.ti;
1409 : unsigned char tmpbuf[2048]; /* for the sig algo and bitstr */
1410 : size_t n, n2;
1411 :
1412 : /* We do read the stuff into a temporary buffer so that we can apply
1413 : our parsing function for this structure */
1414 :
1415 : /* read the algorithmIdentifier sequence */
1416 2 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_SEQUENCE
1417 1 : && ti.is_constructed) )
1418 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
1419 1 : if (ti.ndef)
1420 0 : return gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
1421 1 : n = ti.nhdr + ti.length;
1422 1 : if (n >= DIM(tmpbuf))
1423 0 : return gpg_error (GPG_ERR_TOO_LARGE);
1424 1 : memcpy (tmpbuf, ti.buf, ti.nhdr);
1425 1 : err = read_buffer (crl->reader, tmpbuf+ti.nhdr, ti.length);
1426 1 : if (err)
1427 0 : return err;
1428 :
1429 : /* and append the bit string */
1430 1 : err = _ksba_ber_read_tl (crl->reader, &ti);
1431 1 : if (err)
1432 0 : return err;
1433 2 : if ( !(ti.class == CLASS_UNIVERSAL && ti.tag == TYPE_BIT_STRING
1434 1 : && !ti.is_constructed) )
1435 0 : return gpg_error (GPG_ERR_INV_CRL_OBJ);
1436 1 : n2 = ti.nhdr + ti.length;
1437 1 : if (n + n2 >= DIM(tmpbuf))
1438 0 : return gpg_error (GPG_ERR_TOO_LARGE);
1439 1 : memcpy (tmpbuf+n, ti.buf, ti.nhdr);
1440 1 : err = read_buffer (crl->reader, tmpbuf+n+ti.nhdr, ti.length);
1441 1 : if (err)
1442 0 : return err;
1443 :
1444 : /* now parse it */
1445 1 : xfree (crl->sigval); crl->sigval = NULL;
1446 1 : return _ksba_sigval_to_sexp (tmpbuf, n + n2, &crl->sigval);
1447 : }
1448 :
1449 :
1450 : /* The actual parser which should be used with a new CRL object and
1451 : run in a loop until the the KSBA_SR_READY is encountered */
1452 : gpg_error_t
1453 13 : ksba_crl_parse (ksba_crl_t crl, ksba_stop_reason_t *r_stopreason)
1454 : {
1455 : enum {
1456 : sSTART,
1457 : sCRLENTRY,
1458 : sCRLEXT,
1459 : sERROR
1460 13 : } state = sERROR;
1461 : ksba_stop_reason_t stop_reason;
1462 13 : gpg_error_t err = 0;
1463 13 : int got_entry = 0;
1464 :
1465 13 : if (!crl || !r_stopreason)
1466 0 : return gpg_error (GPG_ERR_INV_VALUE);
1467 :
1468 13 : if (!crl->any_parse_done)
1469 : { /* first time initialization of the stop reason */
1470 1 : *r_stopreason = 0;
1471 1 : crl->any_parse_done = 1;
1472 : }
1473 :
1474 : /* Calculate state from last reason */
1475 13 : stop_reason = *r_stopreason;
1476 13 : *r_stopreason = KSBA_SR_RUNNING;
1477 13 : switch (stop_reason)
1478 : {
1479 : case 0:
1480 1 : state = sSTART;
1481 1 : break;
1482 : case KSBA_SR_BEGIN_ITEMS:
1483 : case KSBA_SR_GOT_ITEM:
1484 11 : state = sCRLENTRY;
1485 11 : break;
1486 : case KSBA_SR_END_ITEMS:
1487 1 : state = sCRLEXT;
1488 1 : break;
1489 : case KSBA_SR_RUNNING:
1490 0 : err = gpg_error (GPG_ERR_INV_STATE);
1491 0 : break;
1492 : default:
1493 0 : err = gpg_error (GPG_ERR_BUG);
1494 0 : break;
1495 : }
1496 13 : if (err)
1497 0 : return err;
1498 :
1499 : /* Do the action */
1500 13 : switch (state)
1501 : {
1502 : case sSTART:
1503 1 : err = parse_to_next_update (crl);
1504 1 : break;
1505 : case sCRLENTRY:
1506 11 : err = parse_crl_entry (crl, &got_entry);
1507 11 : break;
1508 : case sCRLEXT:
1509 1 : err = parse_crl_extensions (crl);
1510 1 : if (!err)
1511 : {
1512 1 : if (crl->hash_fnc && crl->hashbuf.used)
1513 0 : crl->hash_fnc (crl->hash_fnc_arg,
1514 0 : crl->hashbuf.buffer, crl->hashbuf.used);
1515 1 : crl->hashbuf.used = 0;
1516 1 : err = parse_signature (crl);
1517 : }
1518 1 : break;
1519 : default:
1520 0 : err = gpg_error (GPG_ERR_INV_STATE);
1521 0 : break;
1522 : }
1523 13 : if (err)
1524 0 : return err;
1525 :
1526 : /* Calculate new stop reason */
1527 13 : switch (state)
1528 : {
1529 : case sSTART:
1530 1 : stop_reason = KSBA_SR_BEGIN_ITEMS;
1531 1 : break;
1532 : case sCRLENTRY:
1533 11 : stop_reason = got_entry? KSBA_SR_GOT_ITEM : KSBA_SR_END_ITEMS;
1534 11 : break;
1535 : case sCRLEXT:
1536 1 : stop_reason = KSBA_SR_READY;
1537 1 : break;
1538 : default:
1539 0 : break;
1540 : }
1541 :
1542 13 : *r_stopreason = stop_reason;
1543 13 : return 0;
1544 : }
|