Bug Summary

File:lib/opencdk/keydb.c
Location:line 1278, column 7
Description:Dereference of null pointer

Annotated Source Code

1/* keydb.c - Key database routines
2 * Copyright (C) 2002-2003, 2007-2010, 2012 Free Software Foundation,
3 * Inc.
4 *
5 * Author: Timo Schulz
6 *
7 * This file is part of OpenCDK.
8 *
9 * The OpenCDK library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 3 of
12 * the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>
21 *
22 */
23#ifdef HAVE_CONFIG_H1
24#include <config.h>
25#endif
26#include <sys/stat.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <ctype.h>
31
32#include "opencdk.h"
33#include "main.h"
34#include "packet.h"
35#include "filters.h"
36#include "stream.h"
37#include "keydb.h"
38
39#define KEYID_CMP(a, b)((a[0]) == (b[0]) && (a[1]) == (b[1])) ((a[0]) == (b[0]) && (a[1]) == (b[1]))
40#define KEYDB_CACHE_ENTRIES8 8
41
42static void keydb_cache_free (key_table_t cache);
43static int classify_data (const byte * buf, size_t len);
44static cdk_kbnode_t find_selfsig_node (cdk_kbnode_t key, cdk_pkt_pubkey_t pk);
45
46static char *
47keydb_idx_mkname (const char *file)
48{
49 static const char *fmt = "%s.idx";
50 char *fname;
51 size_t len = strlen (file) + strlen (fmt);
52
53 fname = cdk_callocgnutls_calloc (1, len + 1);
54 if (!fname)
55 return NULL((void*)0);
56 if (snprintf (fname, len, fmt, file) <= 0)
57 return NULL((void*)0);
58 return fname;
59}
60
61
62/* This functions builds an index of the keyring into a separate file
63 with the name keyring.ext.idx. It contains the offset of all public-
64 and public subkeys. The format of the file is:
65 --------
66 4 octets offset of the packet
67 8 octets keyid
68 20 octets fingerprint
69 --------
70 We store the keyid and the fingerprint due to the fact we can't get
71 the keyid from a v3 fingerprint directly.
72*/
73static cdk_error_t
74keydb_idx_build (const char *file)
75{
76 cdk_packet_t pkt;
77 cdk_stream_t inp, out = NULL((void*)0);
78 byte buf[4 + 8 + KEY_FPR_LEN20];
79 char *idx_name;
80 u32 keyid[2];
81 cdk_error_t rc;
82
83 if (!file)
84 {
85 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",85); } while(0);
;
86 return CDK_Inv_Value;
87 }
88
89 rc = cdk_stream_open (file, &inp);
90 if (rc)
91 {
92 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",92); } while(0);
;
93 return rc;
94 }
95
96 idx_name = keydb_idx_mkname (file);
97 if (!idx_name)
98 {
99 cdk_stream_close (inp);
100 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",100); } while(0);
;
101 return CDK_Out_Of_Core;
102 }
103 rc = cdk_stream_create (idx_name, &out);
104 cdk_freegnutls_free (idx_name);
105 if (rc)
106 {
107 cdk_stream_close (inp);
108 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",108); } while(0);
;
109 return rc;
110 }
111
112 cdk_pkt_new (&pkt);
113 while (!cdk_stream_eof (inp))
114 {
115 off_t pos = cdk_stream_tell (inp);
116
117 rc = cdk_pkt_read (inp, pkt);
118 if (rc)
119 {
120 _cdk_log_debug ("index build failed packet off=%lu\n", pos)do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "index build failed packet off=%lu\n", pos); } while(0)
;
121 /* FIXME: The index is incomplete */
122 break;
123 }
124 if (pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
125 pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
126 {
127 _cdk_u32tobuf (pos, buf);
128 cdk_pk_get_keyid (pkt->pkt.public_key, keyid);
129 _cdk_u32tobuf (keyid[0], buf + 4);
130 _cdk_u32tobuf (keyid[1], buf + 8);
131 cdk_pk_get_fingerprint (pkt->pkt.public_key, buf + 12);
132 cdk_stream_write (out, buf, 4 + 8 + KEY_FPR_LEN20);
133 }
134 cdk_pkt_free (pkt);
135 }
136
137 cdk_pkt_release (pkt);
138
139 cdk_stream_close (out);
140 cdk_stream_close (inp);
141 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",141); } while(0);
;
142 return rc;
143}
144
145
146/**
147 * cdk_keydb_idx_rebuild:
148 * @hd: key database handle
149 *
150 * Rebuild the key index files for the given key database.
151 **/
152cdk_error_t
153cdk_keydb_idx_rebuild (cdk_keydb_hd_t db, cdk_keydb_search_t dbs)
154{
155 struct stat stbuf;
156 char *tmp_idx_name;
157 cdk_error_t rc;
158 int err;
159
160 if (!db || !db->name || !dbs)
161 {
162 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",162); } while(0);
;
163 return CDK_Inv_Value;
164 }
165 if (db->secret)
166 return 0;
167
168 tmp_idx_name = keydb_idx_mkname (db->name);
169 if (!tmp_idx_name)
170 {
171 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",171); } while(0);
;
172 return CDK_Out_Of_Core;
173 }
174 err = stat (tmp_idx_name, &stbuf);
175 cdk_freegnutls_free (tmp_idx_name);
176 /* This function expects an existing index which can be rebuild,
177 if no index exists we do not build one and just return. */
178 if (err)
179 return 0;
180
181 cdk_stream_close (dbs->idx);
182 dbs->idx = NULL((void*)0);
183 if (!dbs->idx_name)
184 {
185 dbs->idx_name = keydb_idx_mkname (db->name);
186 if (!dbs->idx_name)
187 {
188 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",188); } while(0);
;
189 return CDK_Out_Of_Core;
190 }
191 }
192 rc = keydb_idx_build (db->name);
193 if (!rc)
194 rc = cdk_stream_open (dbs->idx_name, &dbs->idx);
195 else
196 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",196); } while(0);
;
197 return rc;
198}
199
200
201static cdk_error_t
202keydb_idx_parse (cdk_stream_t inp, key_idx_t * r_idx)
203{
204 key_idx_t idx;
205 byte buf[4];
206
207 if (!inp || !r_idx)
208 {
209 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",209); } while(0);
;
210 return CDK_Inv_Value;
211 }
212
213 idx = cdk_callocgnutls_calloc (1, sizeof *idx);
214 if (!idx)
215 {
216 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",216); } while(0);
;
217 return CDK_Out_Of_Core;
218 }
219
220 while (!cdk_stream_eof (inp))
221 {
222 if (cdk_stream_read (inp, buf, 4) == CDK_EOF)
223 break;
224 idx->offset = _cdk_buftou32 (buf);
225 cdk_stream_read (inp, buf, 4);
226 idx->keyid[0] = _cdk_buftou32 (buf);
227 cdk_stream_read (inp, buf, 4);
228 idx->keyid[1] = _cdk_buftou32 (buf);
229 cdk_stream_read (inp, idx->fpr, KEY_FPR_LEN20);
230 break;
231 }
232 *r_idx = idx;
233 return cdk_stream_eof (inp) ? CDK_EOF : 0;
234}
235
236
237static cdk_error_t
238keydb_idx_search (cdk_stream_t inp, u32 * keyid, const byte * fpr,
239 off_t * r_off)
240{
241 key_idx_t idx;
242
243 if (!inp || !r_off)
244 {
245 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",245); } while(0);
;
246 return CDK_Inv_Value;
247 }
248 if ((keyid && fpr) || (!keyid && !fpr))
249 {
250 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",250); } while(0);
;
251 return CDK_Inv_Mode;
252 }
253
254 /* We need an initialize the offset var with a value
255 because it might be possible the returned offset will
256 be 0 and then we cannot differ between the begin and an EOF. */
257 *r_off = 0xFFFFFFFF;
258 cdk_stream_seek (inp, 0);
259 while (keydb_idx_parse (inp, &idx) != CDK_EOF)
260 {
261 if (keyid && KEYID_CMP (keyid, idx->keyid)((keyid[0]) == (idx->keyid[0]) && (keyid[1]) == (idx
->keyid[1]))
)
262 {
263 *r_off = idx->offset;
264 break;
265 }
266 else if (fpr && !memcmp (idx->fpr, fpr, KEY_FPR_LEN20))
267 {
268 *r_off = idx->offset;
269 break;
270 }
271 cdk_freegnutls_free (idx);
272 idx = NULL((void*)0);
273 }
274 cdk_freegnutls_free (idx);
275 return *r_off != 0xFFFFFFFF ? 0 : CDK_EOF;
276}
277
278
279/**
280 * cdk_keydb_new_from_mem:
281 * @r_hd: The keydb output handle.
282 * @secret: does the stream contain secret key data
283 * @armor: the stream is base64
284 * @data: The raw key data.
285 * @datlen: The length of the raw data.
286 *
287 * Create a new keyring db handle from the contents of a buffer.
288 */
289cdk_error_t
290cdk_keydb_new_from_mem (cdk_keydb_hd_t * r_db, int secret, int armor,
291 const void *data, size_t datlen)
292{
293 cdk_keydb_hd_t db;
294 cdk_error_t rc;
295
296 if (!r_db)
297 {
298 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",298); } while(0);
;
299 return CDK_Inv_Value;
300 }
301 *r_db = NULL((void*)0);
302 db = calloc (1, sizeof *db);
303 rc = cdk_stream_tmp_from_mem (data, datlen, &db->fp);
304 if (!db->fp)
305 {
306 cdk_freegnutls_free (db);
307 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",307); } while(0);
;
308 return rc;
309 }
310
311 if (armor)
312 cdk_stream_set_armor_flag (db->fp, 0);
313 db->type = CDK_DBTYPE_DATA;
314 db->secret = secret;
315 *r_db = db;
316 return 0;
317}
318
319/**
320 * cdk_keydb_free:
321 * @hd: the keydb object
322 *
323 * Free the keydb object.
324 **/
325void
326cdk_keydb_free (cdk_keydb_hd_t hd)
327{
328 if (!hd)
329 return;
330
331 if (hd->name)
332 {
333 cdk_freegnutls_free (hd->name);
334 hd->name = NULL((void*)0);
335 }
336
337 if (hd->fp && !hd->fp_ref)
338 {
339 cdk_stream_close (hd->fp);
340 hd->fp = NULL((void*)0);
341 }
342
343
344 hd->isopen = 0;
345 hd->secret = 0;
346 cdk_freegnutls_free (hd);
347}
348
349
350static cdk_error_t
351_cdk_keydb_open (cdk_keydb_hd_t hd, cdk_stream_t * ret_kr)
352{
353 cdk_error_t rc;
354 cdk_stream_t kr;
355
356 if (!hd || !ret_kr)
357 {
358 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",358); } while(0);
;
359 return CDK_Inv_Value;
360 }
361
362 rc = 0;
363 if ((hd->type == CDK_DBTYPE_DATA)
364 && hd->fp)
365 {
366 kr = hd->fp;
367 cdk_stream_seek (kr, 0);
368 }
369 else if (hd->type == CDK_DBTYPE_PK_KEYRING ||
370 hd->type == CDK_DBTYPE_SK_KEYRING)
371 {
372 rc = cdk_stream_open (hd->name, &kr);
373
374 if (rc)
375 goto leave;
376 }
377 else
378 {
379 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",379); } while(0);
;
380 return CDK_Inv_Mode;
381 }
382
383leave:
384
385 *ret_kr = kr;
386 return rc;
387}
388
389
390static int
391find_by_keyid (cdk_kbnode_t knode, cdk_keydb_search_t ks)
392{
393 cdk_kbnode_t node;
394 u32 keyid[2];
395
396 for (node = knode; node; node = node->next)
397 {
398 if (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
399 node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY ||
400 node->pkt->pkttype == CDK_PKT_SECRET_KEY ||
401 node->pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
402 {
403 _cdk_pkt_get_keyid (node->pkt, keyid);
404 switch (ks->type)
405 {
406 case CDK_DBSEARCH_SHORT_KEYID:
407 if (keyid[1] == ks->u.keyid[1])
408 return 1;
409 break;
410
411 case CDK_DBSEARCH_KEYID:
412 if (KEYID_CMP (keyid, ks->u.keyid)((keyid[0]) == (ks->u.keyid[0]) && (keyid[1]) == (
ks->u.keyid[1]))
)
413 return 1;
414 break;
415
416 default:
417 _cdk_log_debug ("find_by_keyid: invalid mode = %d\n", ks->type)do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "find_by_keyid: invalid mode = %d\n", ks->type); } while
(0)
;
418 return 0;
419 }
420 }
421 }
422 return 0;
423}
424
425
426static int
427find_by_fpr (cdk_kbnode_t knode, cdk_keydb_search_t ks)
428{
429 cdk_kbnode_t node;
430 byte fpr[KEY_FPR_LEN20];
431
432 if (ks->type != CDK_DBSEARCH_FPR)
433 return 0;
434
435 for (node = knode; node; node = node->next)
436 {
437 if (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
438 node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY ||
439 node->pkt->pkttype == CDK_PKT_SECRET_KEY ||
440 node->pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
441 {
442 _cdk_pkt_get_fingerprint (node->pkt, fpr);
443 if (!memcmp (ks->u.fpr, fpr, KEY_FPR_LEN20))
444 return 1;
445 break;
446 }
447 }
448
449 return 0;
450}
451
452
453static int
454find_by_pattern (cdk_kbnode_t knode, cdk_keydb_search_t ks)
455{
456 cdk_kbnode_t node;
457 size_t uidlen;
458 char *name;
459
460 for (node = knode; node; node = node->next)
461 {
462 if (node->pkt->pkttype != CDK_PKT_USER_ID)
463 continue;
464 if (node->pkt->pkt.user_id->attrib_img != NULL((void*)0))
465 continue; /* Skip attribute packets. */
466 uidlen = node->pkt->pkt.user_id->len;
467 name = node->pkt->pkt.user_id->name;
468 switch (ks->type)
469 {
470 case CDK_DBSEARCH_EXACT:
471 if (name &&
472 (strlen (ks->u.pattern) == uidlen &&
473 !strncmp (ks->u.pattern, name, uidlen)))
474 return 1;
475 break;
476
477 case CDK_DBSEARCH_SUBSTR:
478 if (uidlen > 65536)
479 break;
480 if (name && strlen (ks->u.pattern) > uidlen)
481 break;
482 if (name && _cdk_memistr (name, uidlen, ks->u.pattern))
483 return 1;
484 break;
485
486 default: /* Invalid mode */
487 return 0;
488 }
489 }
490 return 0;
491}
492
493
494static void
495keydb_cache_free (key_table_t cache)
496{
497 key_table_t c2;
498
499 while (cache)
500 {
501 c2 = cache->next;
502 cache->offset = 0;
503 cdk_freegnutls_free (cache);
504 cache = c2;
505 }
506}
507
508
509static key_table_t
510keydb_cache_find (cdk_keydb_search_t desc)
511{
512 key_table_t cache = desc->cache;
513 key_table_t t;
514
515 for (t = cache; t; t = t->next)
516 {
517 switch (desc->type)
518 {
519 case CDK_DBSEARCH_SHORT_KEYID:
520 case CDK_DBSEARCH_KEYID:
521 if (KEYID_CMP (desc->u.keyid, desc->u.keyid)((desc->u.keyid[0]) == (desc->u.keyid[0]) && (desc
->u.keyid[1]) == (desc->u.keyid[1]))
)
522 return t;
523 break;
524
525 case CDK_DBSEARCH_EXACT:
526 if (strlen (desc->u.pattern) == strlen (desc->u.pattern) &&
527 !strcmp (desc->u.pattern, desc->u.pattern))
528 return t;
529 break;
530
531 case CDK_DBSEARCH_SUBSTR:
532 if (strstr (desc->u.pattern, desc->u.pattern))
533 return t;
534 break;
535
536 case CDK_DBSEARCH_FPR:
537 if (!memcmp (desc->u.fpr, desc->u.fpr, KEY_FPR_LEN20))
538 return t;
539 break;
540 }
541 }
542
543 return NULL((void*)0);
544}
545
546
547static cdk_error_t
548keydb_cache_add (cdk_keydb_search_t dbs, off_t offset)
549{
550 key_table_t k;
551
552 if (dbs->ncache > KEYDB_CACHE_ENTRIES8)
553 return 0; /* FIXME: we should replace the last entry. */
554 k = cdk_callocgnutls_calloc (1, sizeof *k);
555 if (!k)
556 {
557 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",557); } while(0);
;
558 return CDK_Out_Of_Core;
559 }
560
561 k->offset = offset;
562
563 k->next = dbs->cache;
564 dbs->cache = k;
565 dbs->ncache++;
566 _cdk_log_debug ("cache: add entry off=%d type=%d\n", (int) offset,do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "cache: add entry off=%d type=%d\n", (int) offset, (int)
dbs->type); } while(0)
567 (int) dbs->type)do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "cache: add entry off=%d type=%d\n", (int) offset, (int)
dbs->type); } while(0)
;
568 return 0;
569}
570
571static cdk_error_t
572idx_init (cdk_keydb_hd_t db, cdk_keydb_search_t dbs)
573{
574 cdk_error_t ec, rc = 0;
575
576 if (cdk_stream_get_length (db->fp) < 524288)
577 {
578 dbs->no_cache = 1;
579 goto leave;
580 }
581
582 dbs->idx_name = keydb_idx_mkname (db->name);
583 if (!dbs->idx_name)
584 {
585 rc = CDK_Out_Of_Core;
586 goto leave;
587 }
588 ec = cdk_stream_open (dbs->idx_name, &dbs->idx);
589
590 if (ec && !db->secret)
591 {
592 rc = keydb_idx_build (db->name);
593 if (!rc)
594 rc = cdk_stream_open (dbs->idx_name, &dbs->idx);
595 if (!rc)
596 {
597 _cdk_log_debug ("create key index table\n")do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "create key index table\n"); } while(0)
;
598 }
599 else
600 {
601 /* This is no real error, it just means we can't create
602 the index at the given directory. maybe we've no write
603 access. in this case, we simply disable the index. */
604 _cdk_log_debug ("disable key index table err=%d\n", rc)do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "disable key index table err=%d\n", rc); } while(0)
;
605 rc = 0;
606 dbs->no_cache = 1;
607 }
608 }
609
610leave:
611
612 return rc;
613}
614
615/**
616 * cdk_keydb_search_start:
617 * @st: search handle
618 * @db: key database handle
619 * @type: specifies the search type
620 * @desc: description which depends on the type
621 *
622 * Create a new keydb search object.
623 **/
624cdk_error_t
625cdk_keydb_search_start (cdk_keydb_search_t * st, cdk_keydb_hd_t db, int type,
626 void *desc)
627{
628 u32 *keyid;
629 char *p, tmp[3];
630 int i;
631 cdk_error_t rc;
632
633 if (!db)
634 {
635 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",635); } while(0);
;
636 return CDK_Inv_Value;
637 }
638 if (type != CDK_DBSEARCH_NEXT && !desc)
639 {
640 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",640); } while(0);
;
641 return CDK_Inv_Mode;
642 }
643
644 *st = cdk_callocgnutls_calloc (1, sizeof (cdk_keydb_search_s));
645 if (!(*st))
646 {
647 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",647); } while(0);
;
648 return CDK_Out_Of_Core;
649 }
650
651 rc = idx_init (db, *st);
652 if (rc != CDK_Success)
653 {
654 free (*st);
655 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",655); } while(0);
;
656 return rc;
657 }
658
659 (*st)->type = type;
660 switch (type)
661 {
662 case CDK_DBSEARCH_EXACT:
663 case CDK_DBSEARCH_SUBSTR:
664 cdk_freegnutls_free ((*st)->u.pattern);
665 (*st)->u.pattern = cdk_strdupgnutls_strdup (desc);
666 if (!(*st)->u.pattern)
667 {
668 cdk_freegnutls_free (*st);
669 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",669); } while(0);
;
670 return CDK_Out_Of_Core;
671 }
672 break;
673
674 case CDK_DBSEARCH_SHORT_KEYID:
675 keyid = desc;
676 (*st)->u.keyid[1] = keyid[0];
677 break;
678
679 case CDK_DBSEARCH_KEYID:
680 keyid = desc;
681 (*st)->u.keyid[0] = keyid[0];
682 (*st)->u.keyid[1] = keyid[1];
683 break;
684
685 case CDK_DBSEARCH_FPR:
686 memcpy ((*st)->u.fpr, desc, KEY_FPR_LEN20);
687 break;
688
689 case CDK_DBSEARCH_NEXT:
690 break;
691
692 case CDK_DBSEARCH_AUTO:
693 /* Override the type with the actual db search type. */
694 (*st)->type = classify_data (desc, strlen (desc));
695 switch ((*st)->type)
696 {
697 case CDK_DBSEARCH_SUBSTR:
698 case CDK_DBSEARCH_EXACT:
699 cdk_freegnutls_free ((*st)->u.pattern);
700 p = (*st)->u.pattern = cdk_strdupgnutls_strdup (desc);
701 if (!p)
702 {
703 cdk_freegnutls_free (*st);
704 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",704); } while(0);
;
705 return CDK_Out_Of_Core;
706 }
707 break;
708
709 case CDK_DBSEARCH_SHORT_KEYID:
710 case CDK_DBSEARCH_KEYID:
711 p = desc;
712 if (!strncmp (p, "0x", 2))
713 p += 2;
714 if (strlen (p) == 8)
715 {
716 (*st)->u.keyid[0] = 0;
717 (*st)->u.keyid[1] = strtoul (p, NULL((void*)0), 16);
718 }
719 else if (strlen (p) == 16)
720 {
721 (*st)->u.keyid[0] = strtoul (p, NULL((void*)0), 16);
722 (*st)->u.keyid[1] = strtoul (p + 8, NULL((void*)0), 16);
723 }
724 else
725 { /* Invalid key ID object. */
726 cdk_freegnutls_free (*st);
727 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",727); } while(0);
;
728 return CDK_Inv_Mode;
729 }
730 break;
731
732 case CDK_DBSEARCH_FPR:
733 p = desc;
734 if (strlen (p) != 2 * KEY_FPR_LEN20)
735 {
736 cdk_freegnutls_free (*st);
737 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",737); } while(0);
;
738 return CDK_Inv_Mode;
739 }
740 for (i = 0; i < KEY_FPR_LEN20; i++)
741 {
742 tmp[0] = p[2 * i];
743 tmp[1] = p[2 * i + 1];
744 tmp[2] = 0x00;
745 (*st)->u.fpr[i] = strtoul (tmp, NULL((void*)0), 16);
746 }
747 break;
748 }
749 break;
750
751 default:
752 cdk_freegnutls_free (*st);
753 _cdk_log_debug ("cdk_keydb_search_start: invalid mode = %d\n", type)do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "cdk_keydb_search_start: invalid mode = %d\n", type); } while
(0)
;
754 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",754); } while(0);
;
755 return CDK_Inv_Mode;
756 }
757
758 return 0;
759}
760
761
762static cdk_error_t
763keydb_pos_from_cache (cdk_keydb_hd_t hd, cdk_keydb_search_t ks,
764 int *r_cache_hit, off_t * r_off)
765{
766 key_table_t c;
767
768 if (!hd || !r_cache_hit || !r_off)
769 {
770 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",770); } while(0);
;
771 return CDK_Inv_Value;
772 }
773
774 /* Reset the values. */
775 *r_cache_hit = 0;
776 *r_off = 0;
777
778 c = keydb_cache_find (ks);
779 if (c != NULL((void*)0))
780 {
781 _cdk_log_debug ("cache: found entry in cache.\n")do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "cache: found entry in cache.\n"); } while(0)
;
782 *r_cache_hit = 1;
783 *r_off = c->offset;
784 return 0;
785 }
786
787 /* No index cache available so we just return here. */
788 if (!ks->idx)
789 return 0;
790
791 if (ks->idx)
792 {
793 if (ks->type == CDK_DBSEARCH_KEYID)
794 {
795 if (keydb_idx_search (ks->idx, ks->u.keyid, NULL((void*)0), r_off))
796 {
797 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",797); } while(0);
;
798 return CDK_Error_No_Key;
799 }
800 _cdk_log_debug ("cache: found keyid entry in idx table.\n")do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "cache: found keyid entry in idx table.\n"); } while(0)
;
801 *r_cache_hit = 1;
802 }
803 else if (ks->type == CDK_DBSEARCH_FPR)
804 {
805 if (keydb_idx_search (ks->idx, NULL((void*)0), ks->u.fpr, r_off))
806 {
807 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",807); } while(0);
;
808 return CDK_Error_No_Key;
809 }
810 _cdk_log_debug ("cache: found fpr entry in idx table.\n")do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "cache: found fpr entry in idx table.\n"); } while(0)
;
811 *r_cache_hit = 1;
812 }
813 }
814
815 return 0;
816}
817
818void
819cdk_keydb_search_release (cdk_keydb_search_t st)
820{
821 keydb_cache_free (st->cache);
822
823 if (st->idx)
824 cdk_stream_close (st->idx);
825
826 if (!st)
827 return;
828 if (st->type == CDK_DBSEARCH_EXACT || st->type == CDK_DBSEARCH_SUBSTR)
829 cdk_freegnutls_free (st->u.pattern);
830
831 cdk_freegnutls_free (st);
832}
833
834/**
835 * cdk_keydb_search:
836 * @st: the search handle
837 * @hd: the keydb object
838 * @ret_key: kbnode object to store the key
839 *
840 * Search for a key in the given keyring. The search mode is handled
841 * via @ks. If the key was found, @ret_key contains the key data.
842 **/
843cdk_error_t
844cdk_keydb_search (cdk_keydb_search_t st, cdk_keydb_hd_t hd,
845 cdk_kbnode_t * ret_key)
846{
847 cdk_stream_t kr;
848 cdk_kbnode_t knode;
849 cdk_error_t rc = 0;
850 off_t pos = 0, off = 0;
851 int key_found = 0, cache_hit = 0;
852
853 if (!hd || !ret_key || !st)
854 {
855 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",855); } while(0);
;
856 return CDK_Inv_Value;
857 }
858
859 *ret_key = NULL((void*)0);
860 kr = NULL((void*)0);
861
862 rc = _cdk_keydb_open (hd, &kr);
863 if (rc)
864 {
865 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",865); } while(0);
;
866 return rc;
867 }
868
869 if (!st->no_cache)
870 {
871 /* It is possible the index is not up-to-date and thus we do
872 not find the requesed key. In this case, we reset cache hit
873 and continue our normal search procedure. */
874 rc = keydb_pos_from_cache (hd, st, &cache_hit, &off);
875 if (rc)
876 cache_hit = 0;
877 }
878
879 knode = NULL((void*)0);
880
881 while (!key_found && !rc)
882 {
883 if (cache_hit && st->type != CDK_DBSEARCH_NEXT)
884 cdk_stream_seek (kr, off);
885 else if (st->type == CDK_DBSEARCH_NEXT)
886 cdk_stream_seek (kr, st->off);
887
888 pos = cdk_stream_tell (kr);
889
890 rc = cdk_keydb_get_keyblock (kr, &knode);
891
892 if (rc)
893 {
894 if (rc == CDK_EOF)
895 break;
896 else
897 {
898 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",898); } while(0);
;
899 return rc;
900 }
901 }
902
903 switch (st->type)
904 {
905 case CDK_DBSEARCH_SHORT_KEYID:
906 case CDK_DBSEARCH_KEYID:
907 key_found = find_by_keyid (knode, st);
908 break;
909
910 case CDK_DBSEARCH_FPR:
911 key_found = find_by_fpr (knode, st);
912 break;
913
914 case CDK_DBSEARCH_EXACT:
915 case CDK_DBSEARCH_SUBSTR:
916 key_found = find_by_pattern (knode, st);
917 break;
918
919 case CDK_DBSEARCH_NEXT:
920 st->off = cdk_stream_tell (kr);
921 key_found = knode ? 1 : 0;
922 break;
923 }
924
925 if (key_found)
926 {
927 if (!keydb_cache_find (st))
928 keydb_cache_add (st, pos);
929 break;
930 }
931
932 cdk_kbnode_release (knode);
933 knode = NULL((void*)0);
934 }
935
936 if (key_found && rc == CDK_EOF)
937 rc = 0;
938 else if (rc == CDK_EOF && !key_found)
939 {
940 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",940); } while(0);
;
941 rc = CDK_Error_No_Key;
942 }
943 *ret_key = key_found ? knode : NULL((void*)0);
944 return rc;
945}
946
947cdk_error_t
948cdk_keydb_get_bykeyid (cdk_keydb_hd_t hd, u32 * keyid, cdk_kbnode_t * ret_key)
949{
950 cdk_error_t rc;
951 cdk_keydb_search_t st;
952
953 if (!hd || !keyid || !ret_key)
954 {
955 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",955); } while(0);
;
956 return CDK_Inv_Value;
957 }
958
959 rc = cdk_keydb_search_start (&st, hd, CDK_DBSEARCH_KEYID, keyid);
960 if (!rc)
961 rc = cdk_keydb_search (st, hd, ret_key);
962
963 cdk_keydb_search_release (st);
964 return rc;
965}
966
967
968cdk_error_t
969cdk_keydb_get_byfpr (cdk_keydb_hd_t hd, const byte * fpr,
970 cdk_kbnode_t * r_key)
971{
972 cdk_error_t rc;
973 cdk_keydb_search_t st;
974
975 if (!hd || !fpr || !r_key)
976 {
977 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",977); } while(0);
;
978 return CDK_Inv_Value;
979 }
980
981 rc = cdk_keydb_search_start (&st, hd, CDK_DBSEARCH_FPR, (byte *) fpr);
982 if (!rc)
983 rc = cdk_keydb_search (st, hd, r_key);
984
985 cdk_keydb_search_release (st);
986 return rc;
987}
988
989
990cdk_error_t
991cdk_keydb_get_bypattern (cdk_keydb_hd_t hd, const char *patt,
992 cdk_kbnode_t * ret_key)
993{
994 cdk_error_t rc;
995 cdk_keydb_search_t st;
996
997 if (!hd || !patt || !ret_key)
998 {
999 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",999); } while(0);
;
1000 return CDK_Inv_Value;
1001 }
1002
1003 rc = cdk_keydb_search_start (&st, hd, CDK_DBSEARCH_SUBSTR, (char *) patt);
1004 if (!rc)
1005 rc = cdk_keydb_search (st, hd, ret_key);
1006
1007 if (rc)
1008 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1008); } while(0);
;
1009
1010 cdk_keydb_search_release (st);
1011 return rc;
1012}
1013
1014
1015static int
1016keydb_check_key (cdk_packet_t pkt)
1017{
1018 cdk_pkt_pubkey_t pk;
1019 int is_sk, valid;
1020
1021 if (pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
1022 pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
1023 {
1024 pk = pkt->pkt.public_key;
1025 is_sk = 0;
1026 }
1027 else if (pkt->pkttype == CDK_PKT_SECRET_KEY ||
1028 pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
1029 {
1030 pk = pkt->pkt.secret_key->pk;
1031 is_sk = 1;
1032 }
1033 else /* No key object. */
1034 return 0;
1035 valid = !pk->is_revoked && !pk->has_expired;
1036 if (is_sk)
1037 return valid;
1038 return valid && !pk->is_invalid;
1039}
1040
1041
1042/* Find the first kbnode with the requested packet type
1043 that represents a valid key. */
1044static cdk_kbnode_t
1045kbnode_find_valid (cdk_kbnode_t root, cdk_packet_type_t pkttype)
1046{
1047 cdk_kbnode_t n;
1048
1049 for (n = root; n; n = n->next)
1050 {
1051 if (n->pkt->pkttype != pkttype)
1052 continue;
1053 if (keydb_check_key (n->pkt))
1054 return n;
1055 }
1056
1057 return NULL((void*)0);
1058}
1059
1060
1061static cdk_kbnode_t
1062keydb_find_byusage (cdk_kbnode_t root, int req_usage, int is_pk)
1063{
1064 cdk_kbnode_t node, key;
1065 int req_type;
1066 long timestamp;
1067
1068 req_type = is_pk ? CDK_PKT_PUBLIC_KEY : CDK_PKT_SECRET_KEY;
1069 if (!req_usage)
1070 return kbnode_find_valid (root, req_type);
1071
1072 node = cdk_kbnode_find (root, req_type);
1073 if (node && !keydb_check_key (node->pkt))
1074 return NULL((void*)0);
1075
1076 key = NULL((void*)0);
1077 timestamp = 0;
1078 /* We iteratre over the all nodes and search for keys or
1079 subkeys which match the usage and which are not invalid.
1080 A timestamp is used to figure out the newest valid key. */
1081 for (node = root; node; node = node->next)
1082 {
1083 if (is_pk && (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
1084 node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
1085 && keydb_check_key (node->pkt)
1086 && (node->pkt->pkt.public_key->pubkey_usage & req_usage))
1087 {
1088 if (node->pkt->pkt.public_key->timestamp > timestamp)
1089 key = node;
1090 }
1091 if (!is_pk && (node->pkt->pkttype == CDK_PKT_SECRET_KEY ||
1092 node->pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
1093 && keydb_check_key (node->pkt)
1094 && (node->pkt->pkt.secret_key->pk->pubkey_usage & req_usage))
1095 {
1096 if (node->pkt->pkt.secret_key->pk->timestamp > timestamp)
1097 key = node;
1098 }
1099
1100 }
1101 return key;
1102}
1103
1104
1105static cdk_kbnode_t
1106keydb_find_bykeyid (cdk_kbnode_t root, const u32 * keyid, int search_mode)
1107{
1108 cdk_kbnode_t node;
1109 u32 kid[2];
1110
1111 for (node = root; node; node = node->next)
1112 {
1113 if (!_cdk_pkt_get_keyid (node->pkt, kid))
1114 continue;
1115 if (search_mode == CDK_DBSEARCH_SHORT_KEYID && kid[1] == keyid[1])
1116 return node;
1117 else if (kid[0] == keyid[0] && kid[1] == keyid[1])
1118 return node;
1119 }
1120 return NULL((void*)0);
1121}
1122
1123
1124cdk_error_t
1125_cdk_keydb_get_sk_byusage (cdk_keydb_hd_t hd, const char *name,
1126 cdk_seckey_t * ret_sk, int usage)
1127{
1128 cdk_kbnode_t knode = NULL((void*)0);
1129 cdk_kbnode_t node, sk_node, pk_node;
1130 cdk_pkt_seckey_t sk;
1131 cdk_error_t rc;
1132 const char *s;
1133 int pkttype;
1134 cdk_keydb_search_t st;
1135
1136 if (!ret_sk || !usage)
1137 {
1138 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1138); } while(0);
;
1139 return CDK_Inv_Value;
1140 }
1141
1142 if (!hd)
1143 {
1144 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1144); } while(0);
;
1145 return CDK_Error_No_Keyring;
1146 }
1147
1148 *ret_sk = NULL((void*)0);
1149 rc = cdk_keydb_search_start (&st, hd, CDK_DBSEARCH_AUTO, (char *) name);
1150 if (rc)
1151 {
1152 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1152); } while(0);
;
1153 return rc;
1154 }
1155
1156 rc = cdk_keydb_search (st, hd, &knode);
1157 if (rc)
1158 {
1159 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1159); } while(0);
;
1160 return rc;
1161 }
1162
1163 cdk_keydb_search_release (st);
1164
1165 sk_node = keydb_find_byusage (knode, usage, 0);
1166 if (!sk_node)
1167 {
1168 cdk_kbnode_release (knode);
1169 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1169); } while(0);
;
1170 return CDK_Unusable_Key;
1171 }
1172
1173 /* We clone the node with the secret key to avoid that the
1174 packet will be released. */
1175 _cdk_kbnode_clone (sk_node);
1176 sk = sk_node->pkt->pkt.secret_key;
1177
1178 for (node = knode; node; node = node->next)
1179 {
1180 if (node->pkt->pkttype == CDK_PKT_USER_ID)
1181 {
1182 s = node->pkt->pkt.user_id->name;
1183 if (sk && !sk->pk->uid && _cdk_memistr (s, strlen (s), name))
1184 {
1185 _cdk_copy_userid (&sk->pk->uid, node->pkt->pkt.user_id);
1186 break;
1187 }
1188 }
1189 }
1190
1191 /* To find the self signature, we need the primary public key because
1192 the selected secret key might be different from the primary key. */
1193 pk_node = cdk_kbnode_find (knode, CDK_PKT_SECRET_KEY);
1194 if (!pk_node)
1195 {
1196 cdk_kbnode_release (knode);
1197 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1197); } while(0);
;
1198 return CDK_Unusable_Key;
1199 }
1200 node = find_selfsig_node (knode, pk_node->pkt->pkt.secret_key->pk);
1201 if (sk->pk->uid && node)
1202 _cdk_copy_signature (&sk->pk->uid->selfsig, node->pkt->pkt.signature);
1203
1204 /* We only release the outer packet. */
1205 _cdk_pkt_detach_free (sk_node->pkt, &pkttype, (void *) &sk);
1206 cdk_kbnode_release (knode);
1207 *ret_sk = sk;
1208 return rc;
1209}
1210
1211
1212cdk_error_t
1213_cdk_keydb_get_pk_byusage (cdk_keydb_hd_t hd, const char *name,
1214 cdk_pubkey_t * ret_pk, int usage)
1215{
1216 cdk_kbnode_t knode, node, pk_node;
1217 cdk_pkt_pubkey_t pk;
1218 const char *s;
1219 cdk_error_t rc;
1220 cdk_keydb_search_t st;
1221
1222 if (!ret_pk || !usage)
1
Taking false branch
1223 {
1224 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1224); } while(0);
;
1225 return CDK_Inv_Value;
1226 }
1227 if (!hd)
2
Taking false branch
1228 {
1229 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1229); } while(0);
;
1230 return CDK_Error_No_Keyring;
1231 }
1232
1233 *ret_pk = NULL((void*)0);
1234 rc = cdk_keydb_search_start (&st, hd, CDK_DBSEARCH_AUTO, (char *) name);
1235 if (!rc)
3
Taking true branch
1236 rc = cdk_keydb_search (st, hd, &knode);
1237 if (rc)
4
Taking false branch
1238 {
1239 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1239); } while(0);
;
1240 return rc;
1241 }
1242
1243 cdk_keydb_search_release (st);
1244
1245 node = keydb_find_byusage (knode, usage, 1);
1246 if (!node)
5
Taking false branch
1247 {
1248 cdk_kbnode_release (knode);
1249 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1249); } while(0);
;
1250 return CDK_Unusable_Key;
1251 }
1252
1253 pk = NULL((void*)0);
1254 _cdk_copy_pubkey (&pk, node->pkt->pkt.public_key);
1255 for (node = knode; node; node = node->next)
6
Loop condition is true. Entering loop body
10
Loop condition is false. Execution continues on line 1270
1256 {
1257 if (node->pkt->pkttype == CDK_PKT_USER_ID)
7
Taking true branch
1258 {
1259 s = node->pkt->pkt.user_id->name;
1260 if (pk && !pk->uid && _cdk_memistr (s, strlen (s), name))
8
Assuming pointer value is null
9
Taking false branch
1261 {
1262 _cdk_copy_userid (&pk->uid, node->pkt->pkt.user_id);
1263 break;
1264 }
1265 }
1266 }
1267
1268 /* Same as in the sk code, the selected key can be a sub key
1269 and thus we need the primary key to find the self sig. */
1270 pk_node = cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY);
1271 if (!pk_node)
11
Taking false branch
1272 {
1273 cdk_kbnode_release (knode);
1274 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1274); } while(0);
;
1275 return CDK_Unusable_Key;
1276 }
1277 node = find_selfsig_node (knode, pk_node->pkt->pkt.public_key);
1278 if (pk->uid && node)
12
Dereference of null pointer
1279 _cdk_copy_signature (&pk->uid->selfsig, node->pkt->pkt.signature);
1280 cdk_kbnode_release (knode);
1281
1282 *ret_pk = pk;
1283 return rc;
1284}
1285
1286
1287/**
1288 * cdk_keydb_get_pk:
1289 * @hd: key db handle
1290 * @keyid: keyid of the key
1291 * @r_pk: the allocated public key
1292 *
1293 * Perform a key database search by keyid and return the raw public
1294 * key without any signatures or user id's.
1295 **/
1296cdk_error_t
1297cdk_keydb_get_pk (cdk_keydb_hd_t hd, u32 * keyid, cdk_pubkey_t * r_pk)
1298{
1299 cdk_kbnode_t knode = NULL((void*)0), node;
1300 cdk_pubkey_t pk;
1301 cdk_error_t rc;
1302 size_t s_type;
1303 int pkttype;
1304 cdk_keydb_search_t st;
1305
1306 if (!keyid || !r_pk)
1307 {
1308 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1308); } while(0);
;
1309 return CDK_Inv_Value;
1310 }
1311 if (!hd)
1312 {
1313 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1313); } while(0);
;
1314 return CDK_Error_No_Keyring;
1315 }
1316
1317 *r_pk = NULL((void*)0);
1318 s_type = !keyid[0] ? CDK_DBSEARCH_SHORT_KEYID : CDK_DBSEARCH_KEYID;
1319 rc = cdk_keydb_search_start (&st, hd, s_type, keyid);
1320 if (rc)
1321 {
1322 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1322); } while(0);
;
1323 return rc;
1324 }
1325 rc = cdk_keydb_search (st, hd, &knode);
1326 cdk_keydb_search_release (st);
1327 if (rc)
1328 {
1329 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1329); } while(0);
;
1330 return rc;
1331 }
1332
1333 node = keydb_find_bykeyid (knode, keyid, s_type);
1334 if (!node)
1335 {
1336 cdk_kbnode_release (knode);
1337 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1337); } while(0);
;
1338 return CDK_Error_No_Key;
1339 }
1340
1341 /* See comment in cdk_keydb_get_sk() */
1342 _cdk_pkt_detach_free (node->pkt, &pkttype, (void *) &pk);
1343 *r_pk = pk;
1344 _cdk_kbnode_clone (node);
1345 cdk_kbnode_release (knode);
1346
1347 return rc;
1348}
1349
1350
1351/**
1352 * cdk_keydb_get_sk:
1353 * @hd: key db handle
1354 * @keyid: the keyid of the key
1355 * @ret_sk: the allocated secret key
1356 *
1357 * Perform a key database search by keyid and return
1358 * only the raw secret key without the additional nodes,
1359 * like the user id or the signatures.
1360 **/
1361cdk_error_t
1362cdk_keydb_get_sk (cdk_keydb_hd_t hd, u32 * keyid, cdk_seckey_t * ret_sk)
1363{
1364 cdk_kbnode_t snode, node;
1365 cdk_seckey_t sk;
1366 cdk_error_t rc;
1367 int pkttype;
1368
1369 if (!keyid || !ret_sk)
1370 {
1371 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1371); } while(0);
;
1372 return CDK_Inv_Value;
1373 }
1374 if (!hd)
1375 {
1376 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1376); } while(0);
;
1377 return CDK_Error_No_Keyring;
1378 }
1379
1380 *ret_sk = NULL((void*)0);
1381 rc = cdk_keydb_get_bykeyid (hd, keyid, &snode);
1382 if (rc)
1383 {
1384 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1384); } while(0);
;
1385 return rc;
1386 }
1387
1388 node = keydb_find_bykeyid (snode, keyid, CDK_DBSEARCH_KEYID);
1389 if (!node)
1390 {
1391 cdk_kbnode_release (snode);
1392 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1392); } while(0);
;
1393 return CDK_Error_No_Key;
1394 }
1395
1396 /* We need to release the packet itself but not its contents
1397 and thus we detach the openpgp packet and release the structure. */
1398 _cdk_pkt_detach_free (node->pkt, &pkttype, (void *) &sk);
1399 _cdk_kbnode_clone (node);
1400 cdk_kbnode_release (snode);
1401
1402 *ret_sk = sk;
1403 return 0;
1404}
1405
1406
1407static int
1408is_selfsig (cdk_kbnode_t node, const u32 * keyid)
1409{
1410 cdk_pkt_signature_t sig;
1411
1412 if (node->pkt->pkttype != CDK_PKT_SIGNATURE)
1413 return 0;
1414 sig = node->pkt->pkt.signature;
1415 if ((sig->sig_class >= 0x10 && sig->sig_class <= 0x13) &&
1416 sig->keyid[0] == keyid[0] && sig->keyid[1] == keyid[1])
1417 return 1;
1418
1419 return 0;
1420}
1421
1422
1423/* Find the newest self signature for the public key @pk
1424 and return the signature node. */
1425static cdk_kbnode_t
1426find_selfsig_node (cdk_kbnode_t key, cdk_pkt_pubkey_t pk)
1427{
1428 cdk_kbnode_t n, sig;
1429 unsigned int ts;
1430 u32 keyid[2];
1431
1432 cdk_pk_get_keyid (pk, keyid);
1433 sig = NULL((void*)0);
1434 ts = 0;
1435 for (n = key; n; n = n->next)
1436 {
1437 if (is_selfsig (n, keyid) && n->pkt->pkt.signature->timestamp > ts)
1438 {
1439 ts = n->pkt->pkt.signature->timestamp;
1440 sig = n;
1441 }
1442 }
1443
1444 return sig;
1445}
1446
1447static unsigned int
1448key_usage_to_cdk_usage (unsigned int usage)
1449{
1450 unsigned key_usage = 0;
1451
1452 if (usage & 0x01) /* cert + sign data */
1453 key_usage |= CDK_KEY_USG_CERT_SIGN;
1454 if (usage & 0x02) /* cert + sign data */
1455 key_usage |= CDK_KEY_USG_DATA_SIGN;
1456 if (usage & 0x04) /* encrypt comm. + storage */
1457 key_usage |= CDK_KEY_USG_COMM_ENCR;
1458 if (usage & 0x08) /* encrypt comm. + storage */
1459 key_usage |= CDK_KEY_USG_STORAGE_ENCR;
1460 if (usage & 0x10) /* encrypt comm. + storage */
1461 key_usage |= CDK_KEY_USG_SPLIT_KEY;
1462 if (usage & 0x20)
1463 key_usage |= CDK_KEY_USG_AUTH;
1464 if (usage & 0x80) /* encrypt comm. + storage */
1465 key_usage |= CDK_KEY_USG_SHARED_KEY;
1466
1467 return key_usage;
1468}
1469
1470static cdk_error_t
1471keydb_merge_selfsig (cdk_kbnode_t key, u32 * keyid)
1472{
1473 cdk_kbnode_t node, kbnode, unode;
1474 cdk_subpkt_t s = NULL((void*)0);
1475 cdk_pkt_signature_t sig = NULL((void*)0);
1476 cdk_pkt_userid_t uid = NULL((void*)0);
1477 const byte *symalg = NULL((void*)0), *hashalg = NULL((void*)0), *compalg = NULL((void*)0);
1478 size_t nsymalg = 0, nhashalg = 0, ncompalg = 0, n = 0;
1479 size_t key_expire = 0;
1480
1481 if (!key)
1482 {
1483 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1483); } while(0);
;
1484 return CDK_Inv_Value;
1485 }
1486
1487 for (node = key; node; node = node->next)
1488 {
1489 if (!is_selfsig (node, keyid))
1490 continue;
1491 unode = cdk_kbnode_find_prev (key, node, CDK_PKT_USER_ID);
1492 if (!unode)
1493 {
1494 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1494); } while(0);
;
1495 return CDK_Error_No_Key;
1496 }
1497 uid = unode->pkt->pkt.user_id;
1498 sig = node->pkt->pkt.signature;
1499 s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_PRIMARY_UID);
1500 if (s)
1501 uid->is_primary = 1;
1502 s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_FEATURES);
1503 if (s && s->size == 1 && s->d[0] & 0x01)
1504 uid->mdc_feature = 1;
1505 s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_KEY_EXPIRE);
1506 if (s && s->size == 4)
1507 key_expire = _cdk_buftou32 (s->d);
1508 s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_PREFS_SYM);
1509 if (s)
1510 {
1511 symalg = s->d;
1512 nsymalg = s->size;
1513 n += s->size + 1;
1514 }
1515 s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_PREFS_HASH);
1516 if (s)
1517 {
1518 hashalg = s->d;
1519 nhashalg = s->size;
1520 n += s->size + 1;
1521 }
1522 s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_PREFS_ZIP);
1523 if (s)
1524 {
1525 compalg = s->d;
1526 ncompalg = s->size;
1527 n += s->size + 1;
1528 }
1529 if (uid->prefs != NULL((void*)0))
1530 cdk_freegnutls_free (uid->prefs);
1531 if (!n || !hashalg || !compalg || !symalg)
1532 uid->prefs = NULL((void*)0);
1533 else
1534 {
1535 uid->prefs = cdk_callocgnutls_calloc (1, sizeof (*uid->prefs) * (n + 1));
1536 if (!uid->prefs)
1537 {
1538 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1538); } while(0);
;
1539 return CDK_Out_Of_Core;
1540 }
1541 n = 0;
1542 for (; nsymalg; nsymalg--, n++)
1543 {
1544 uid->prefs[n].type = CDK_PREFTYPE_SYM;
1545 uid->prefs[n].value = *symalg++;
1546 }
1547 for (; nhashalg; nhashalg--, n++)
1548 {
1549 uid->prefs[n].type = CDK_PREFTYPE_HASH;
1550 uid->prefs[n].value = *hashalg++;
1551 }
1552 for (; ncompalg; ncompalg--, n++)
1553 {
1554 uid->prefs[n].type = CDK_PREFTYPE_ZIP;
1555 uid->prefs[n].value = *compalg++;
1556 }
1557
1558 uid->prefs[n].type = CDK_PREFTYPE_NONE; /* end of list marker */
1559 uid->prefs[n].value = 0;
1560 uid->prefs_size = n;
1561 }
1562 }
1563
1564 /* Now we add the extracted information to the primary key. */
1565 kbnode = cdk_kbnode_find (key, CDK_PKT_PUBLIC_KEY);
1566 if (kbnode)
1567 {
1568 cdk_pkt_pubkey_t pk = kbnode->pkt->pkt.public_key;
1569 if (uid && uid->prefs && n)
1570 {
1571 if (pk->prefs != NULL((void*)0))
1572 cdk_freegnutls_free (pk->prefs);
1573 pk->prefs = _cdk_copy_prefs (uid->prefs);
1574 pk->prefs_size = n;
1575 }
1576 if (key_expire)
1577 {
1578 pk->expiredate = pk->timestamp + key_expire;
1579 pk->has_expired = pk->expiredate > (u32) gnutls_time (NULL((void*)0)) ? 0 : 1;
1580 }
1581
1582 pk->is_invalid = 0;
1583 }
1584
1585 return 0;
1586}
1587
1588
1589static cdk_error_t
1590keydb_parse_allsigs (cdk_kbnode_t knode, cdk_keydb_hd_t hd, int check)
1591{
1592 cdk_kbnode_t node, kb;
1593 cdk_pkt_signature_t sig;
1594 cdk_pkt_pubkey_t pk;
1595 cdk_subpkt_t s = NULL((void*)0);
1596 u32 expiredate = 0, curtime = (u32) gnutls_time (NULL((void*)0));
1597 u32 keyid[2];
1598
1599 if (!knode)
1600 {
1601 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1601); } while(0);
;
1602 return CDK_Inv_Value;
1603 }
1604 if (check && !hd)
1605 {
1606 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1606); } while(0);
;
1607 return CDK_Inv_Mode;
1608 }
1609
1610 kb = cdk_kbnode_find (knode, CDK_PKT_SECRET_KEY);
1611 if (kb)
1612 return 0;
1613
1614 /* Reset */
1615 for (node = knode; node; node = node->next)
1616 {
1617 if (node->pkt->pkttype == CDK_PKT_USER_ID)
1618 node->pkt->pkt.user_id->is_revoked = 0;
1619 else if (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
1620 node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
1621 node->pkt->pkt.public_key->is_revoked = 0;
1622 }
1623
1624 kb = cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY);
1625 if (!kb)
1626 {
1627 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1627); } while(0);
;
1628 return CDK_Wrong_Format;
1629 }
1630 cdk_pk_get_keyid (kb->pkt->pkt.public_key, keyid);
1631
1632 for (node = knode; node; node = node->next)
1633 {
1634 if (node->pkt->pkttype == CDK_PKT_SIGNATURE)
1635 {
1636 sig = node->pkt->pkt.signature;
1637 /* Revocation certificates for primary keys */
1638 if (sig->sig_class == 0x20)
1639 {
1640 kb = cdk_kbnode_find_prev (knode, node, CDK_PKT_PUBLIC_KEY);
1641 if (kb)
1642 {
1643 kb->pkt->pkt.public_key->is_revoked = 1;
1644 if (check)
1645 _cdk_pk_check_sig (hd, kb, node, NULL((void*)0), NULL((void*)0));
1646 }
1647 else
1648 {
1649 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1649); } while(0);
;
1650 return CDK_Error_No_Key;
1651 }
1652 }
1653 /* Revocation certificates for subkeys */
1654 else if (sig->sig_class == 0x28)
1655 {
1656 kb = cdk_kbnode_find_prev (knode, node, CDK_PKT_PUBLIC_SUBKEY);
1657 if (kb)
1658 {
1659 kb->pkt->pkt.public_key->is_revoked = 1;
1660 if (check)
1661 _cdk_pk_check_sig (hd, kb, node, NULL((void*)0), NULL((void*)0));
1662 }
1663 else
1664 {
1665 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1665); } while(0);
;
1666 return CDK_Error_No_Key;
1667 }
1668 }
1669 /* Revocation certifcates for user ID's */
1670 else if (sig->sig_class == 0x30)
1671 {
1672 if (sig->keyid[0] != keyid[0] || sig->keyid[1] != keyid[1])
1673 continue; /* revokes an earlier signature, no userID. */
1674 kb = cdk_kbnode_find_prev (knode, node, CDK_PKT_USER_ID);
1675 if (kb)
1676 {
1677 kb->pkt->pkt.user_id->is_revoked = 1;
1678 if (check)
1679 _cdk_pk_check_sig (hd, kb, node, NULL((void*)0), NULL((void*)0));
1680 }
1681 else
1682 {
1683 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1683); } while(0);
;
1684 return CDK_Error_No_Key;
1685 }
1686 }
1687 /* Direct certificates for primary keys */
1688 else if (sig->sig_class == 0x1F)
1689 {
1690 kb = cdk_kbnode_find_prev (knode, node, CDK_PKT_PUBLIC_KEY);
1691 if (kb)
1692 {
1693 pk = kb->pkt->pkt.public_key;
1694 pk->is_invalid = 0;
1695 s = cdk_subpkt_find (node->pkt->pkt.signature->hashed,
1696 CDK_SIGSUBPKT_KEY_EXPIRE);
1697 if (s)
1698 {
1699 expiredate = _cdk_buftou32 (s->d);
1700 pk->expiredate = pk->timestamp + expiredate;
1701 pk->has_expired = pk->expiredate > curtime ? 0 : 1;
1702 }
1703 if (check)
1704 _cdk_pk_check_sig (hd, kb, node, NULL((void*)0), NULL((void*)0));
1705 }
1706 else
1707 {
1708 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1708); } while(0);
;
1709 return CDK_Error_No_Key;
1710 }
1711 }
1712 /* Direct certificates for subkeys */
1713 else if (sig->sig_class == 0x18)
1714 {
1715 kb = cdk_kbnode_find_prev (knode, node, CDK_PKT_PUBLIC_SUBKEY);
1716 if (kb)
1717 {
1718 pk = kb->pkt->pkt.public_key;
1719 pk->is_invalid = 0;
1720 s = cdk_subpkt_find (node->pkt->pkt.signature->hashed,
1721 CDK_SIGSUBPKT_KEY_EXPIRE);
1722 if (s)
1723 {
1724 expiredate = _cdk_buftou32 (s->d);
1725 pk->expiredate = pk->timestamp + expiredate;
1726 pk->has_expired = pk->expiredate > curtime ? 0 : 1;
1727 }
1728 if (check)
1729 _cdk_pk_check_sig (hd, kb, node, NULL((void*)0), NULL((void*)0));
1730 }
1731 else
1732 {
1733 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1733); } while(0);
;
1734 return CDK_Error_No_Key;
1735 }
1736 }
1737 }
1738 }
1739 node = cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY);
1740 if (node && node->pkt->pkt.public_key->version == 3)
1741 {
1742 /* v3 public keys have no additonal signatures for the key directly.
1743 we say the key is valid when we have at least a self signature. */
1744 pk = node->pkt->pkt.public_key;
1745 for (node = knode; node; node = node->next)
1746 {
1747 if (is_selfsig (node, keyid))
1748 {
1749 pk->is_invalid = 0;
1750 break;
1751 }
1752 }
1753 }
1754 if (node && (node->pkt->pkt.public_key->is_revoked ||
1755 node->pkt->pkt.public_key->has_expired))
1756 {
1757 /* If the primary key has been revoked, mark all subkeys as invalid
1758 because without a primary key they are not useable */
1759 for (node = knode; node; node = node->next)
1760 {
1761 if (node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
1762 node->pkt->pkt.public_key->is_invalid = 1;
1763 }
1764 }
1765
1766 return 0;
1767}
1768
1769static void
1770add_key_usage (cdk_kbnode_t knode, u32 keyid[2], unsigned int usage)
1771{
1772 cdk_kbnode_t p, ctx;
1773 cdk_packet_t pkt;
1774
1775 ctx = NULL((void*)0);
1776 while ((p = cdk_kbnode_walk (knode, &ctx, 0)))
1777 {
1778 pkt = cdk_kbnode_get_packet (p);
1779 if ((pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY
1780 || pkt->pkttype == CDK_PKT_PUBLIC_KEY)
1781 && pkt->pkt.public_key->keyid[0] == keyid[0]
1782 && pkt->pkt.public_key->keyid[1] == keyid[1])
1783 {
1784 pkt->pkt.public_key->pubkey_usage = usage;
1785 return;
1786 }
1787 }
1788 return;
1789}
1790
1791cdk_error_t
1792cdk_keydb_get_keyblock (cdk_stream_t inp, cdk_kbnode_t * r_knode)
1793{
1794 cdk_packet_t pkt;
1795 cdk_kbnode_t knode, node;
1796 cdk_desig_revoker_t revkeys;
1797 cdk_error_t rc;
1798 u32 keyid[2], main_keyid[2];
1799 off_t old_off;
1800 int key_seen, got_key;
1801
1802 if (!inp || !r_knode)
1803 {
1804 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1804); } while(0);
;
1805 return CDK_Inv_Value;
1806 }
1807
1808 /* Reset all values. */
1809 keyid[0] = keyid[1] = 0;
1810 main_keyid[0] = main_keyid[1] = 0;
1811 revkeys = NULL((void*)0);
1812 knode = NULL((void*)0);
1813 key_seen = got_key = 0;
1814
1815 *r_knode = NULL((void*)0);
1816 rc = CDK_EOF;
1817 while (!cdk_stream_eof (inp))
1818 {
1819 cdk_pkt_new (&pkt);
1820 old_off = cdk_stream_tell (inp);
1821 rc = cdk_pkt_read (inp, pkt);
1822 if (rc)
1823 {
1824 cdk_pkt_release (pkt);
1825 if (rc == CDK_EOF)
1826 break;
1827 else
1828 { /* Release all packets we reached so far. */
1829 _cdk_log_debug ("keydb_get_keyblock: error %d\n", rc)do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "keydb_get_keyblock: error %d\n", rc); } while(0)
;
1830 cdk_kbnode_release (knode);
1831 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1831); } while(0);
;
1832 return rc;
1833 }
1834 }
1835
1836 if (pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
1837 pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY ||
1838 pkt->pkttype == CDK_PKT_SECRET_KEY ||
1839 pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
1840 {
1841 if (key_seen && (pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
1842 pkt->pkttype == CDK_PKT_SECRET_KEY))
1843 {
1844 /* The next key starts here so set the file pointer
1845 and leave the loop. */
1846 cdk_stream_seek (inp, old_off);
1847 cdk_pkt_release (pkt);
1848 break;
1849 }
1850 if (pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
1851 pkt->pkttype == CDK_PKT_SECRET_KEY)
1852 {
1853 _cdk_pkt_get_keyid (pkt, main_keyid);
1854 key_seen = 1;
1855 }
1856 else if (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY ||
1857 pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
1858 {
1859 if (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
1860 {
1861 pkt->pkt.public_key->main_keyid[0] = main_keyid[0];
1862 pkt->pkt.public_key->main_keyid[1] = main_keyid[1];
1863 }
1864 else
1865 {
1866 pkt->pkt.secret_key->main_keyid[0] = main_keyid[0];
1867 pkt->pkt.secret_key->main_keyid[1] = main_keyid[1];
1868 }
1869 }
1870 /* We save this for the signature */
1871 _cdk_pkt_get_keyid (pkt, keyid);
1872 got_key = 1;
1873 }
1874 else if (pkt->pkttype == CDK_PKT_USER_ID)
1875 ;
1876 else if (pkt->pkttype == CDK_PKT_SIGNATURE)
1877 {
1878 cdk_subpkt_t s;
1879
1880 pkt->pkt.signature->key[0] = keyid[0];
1881 pkt->pkt.signature->key[1] = keyid[1];
1882 if (pkt->pkt.signature->sig_class == 0x1F &&
1883 pkt->pkt.signature->revkeys)
1884 revkeys = pkt->pkt.signature->revkeys;
1885
1886 s =
1887 cdk_subpkt_find (pkt->pkt.signature->hashed,
1888 CDK_SIGSUBPKT_KEY_FLAGS);
1889 if (s)
1890 {
1891 unsigned int key_usage = key_usage_to_cdk_usage (s->d[0]);
1892 add_key_usage (knode, pkt->pkt.signature->key, key_usage);
1893 }
1894 }
1895 node = cdk_kbnode_new (pkt);
1896 if (!knode)
1897 knode = node;
1898 else
1899 _cdk_kbnode_add (knode, node);
1900 }
1901
1902 if (got_key)
1903 {
1904 keydb_merge_selfsig (knode, main_keyid);
1905 rc = keydb_parse_allsigs (knode, NULL((void*)0), 0);
1906 if (revkeys)
1907 {
1908 node = cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY);
1909 if (node)
1910 node->pkt->pkt.public_key->revkeys = revkeys;
1911 }
1912 }
1913 else
1914 cdk_kbnode_release (knode);
1915 *r_knode = got_key ? knode : NULL((void*)0);
1916
1917 /* It is possible that we are in an EOF condition after we
1918 successfully read a keyblock. For example if the requested
1919 key is the last in the file. */
1920 if (rc == CDK_EOF && got_key)
1921 rc = 0;
1922 return rc;
1923}
1924
1925
1926/* Return the type of the given data. In case it cannot be classified,
1927 a substring search will be performed. */
1928static int
1929classify_data (const byte * buf, size_t len)
1930{
1931 int type;
1932 unsigned int i;
1933
1934 if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X'))
1935 { /* Skip hex prefix. */
1936 buf += 2;
1937 len -= 2;
1938 }
1939
1940 /* The length of the data does not match either a keyid or a fingerprint. */
1941 if (len != 8 && len != 16 && len != 40)
1942 return CDK_DBSEARCH_SUBSTR;
1943
1944 for (i = 0; i < len; i++)
1945 {
1946 if (!isxdigit (buf[i])((*__ctype_b_loc ())[(int) ((buf[i]))] & (unsigned short int
) _ISxdigit)
)
1947 return CDK_DBSEARCH_SUBSTR;
1948 }
1949 if (i != len)
1950 return CDK_DBSEARCH_SUBSTR;
1951 switch (len)
1952 {
1953 case 8:
1954 type = CDK_DBSEARCH_SHORT_KEYID;
1955 break;
1956 case 16:
1957 type = CDK_DBSEARCH_KEYID;
1958 break;
1959 case 40:
1960 type = CDK_DBSEARCH_FPR;
1961 break;
1962 default:
1963 type = CDK_DBSEARCH_SUBSTR;
1964 break;
1965 }
1966
1967 return type;
1968}
1969
1970
1971/**
1972 * cdk_keydb_export:
1973 * @hd: the keydb handle
1974 * @out: the output stream
1975 * @remusr: the list of key pattern to export
1976 *
1977 * Export a list of keys to the given output stream.
1978 * Use string list with names for pattering searching.
1979 * This procedure strips local signatures.
1980 **/
1981cdk_error_t
1982cdk_keydb_export (cdk_keydb_hd_t hd, cdk_stream_t out, cdk_strlist_t remusr)
1983{
1984 cdk_kbnode_t knode, node;
1985 cdk_strlist_t r;
1986 cdk_error_t rc;
1987 int old_ctb;
1988 cdk_keydb_search_t st;
1989
1990 for (r = remusr; r; r = r->next)
1991 {
1992 rc = cdk_keydb_search_start (&st, hd, CDK_DBSEARCH_AUTO, r->d);
1993 if (rc)
1994 {
1995 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",1995); } while(0);
;
1996 return rc;
1997 }
1998 rc = cdk_keydb_search (st, hd, &knode);
1999 cdk_keydb_search_release (st);
2000
2001 if (rc)
2002 {
2003 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2003); } while(0);
;
2004 return rc;
2005 }
2006
2007 node = cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY);
2008 if (!node)
2009 {
2010 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2010); } while(0);
;
2011 return CDK_Error_No_Key;
2012 }
2013
2014 /* If the key is a version 3 key, use the old packet
2015 format for the output. */
2016 if (node->pkt->pkt.public_key->version == 3)
2017 old_ctb = 1;
2018 else
2019 old_ctb = 0;
2020
2021 for (node = knode; node; node = node->next)
2022 {
2023 /* No specified format; skip them */
2024 if (node->pkt->pkttype == CDK_PKT_RING_TRUST)
2025 continue;
2026 /* We never export local signed signatures */
2027 if (node->pkt->pkttype == CDK_PKT_SIGNATURE &&
2028 !node->pkt->pkt.signature->flags.exportable)
2029 continue;
2030 /* Filter out invalid signatures */
2031 if (node->pkt->pkttype == CDK_PKT_SIGNATURE &&
2032 (!KEY_CAN_SIGN (node->pkt->pkt.signature->pubkey_algo)((_cdk_pk_algo_usage ((node->pkt->pkt.signature->pubkey_algo
))) & (CDK_KEY_USG_DATA_SIGN | CDK_KEY_USG_CERT_SIGN))
))
2033 continue;
2034
2035 /* Adjust the ctb flag if needed. */
2036 node->pkt->old_ctb = old_ctb;
2037 rc = cdk_pkt_write (out, node->pkt);
2038 if (rc)
2039 {
2040 cdk_kbnode_release (knode);
2041 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2041); } while(0);
;
2042 return rc;
2043 }
2044 }
2045 cdk_kbnode_release (knode);
2046 knode = NULL((void*)0);
2047 }
2048 return 0;
2049}
2050
2051
2052static cdk_packet_t
2053find_key_packet (cdk_kbnode_t knode, int *r_is_sk)
2054{
2055 cdk_packet_t pkt;
2056
2057 pkt = cdk_kbnode_find_packet (knode, CDK_PKT_PUBLIC_KEY);
2058 if (!pkt)
2059 {
2060 pkt = cdk_kbnode_find_packet (knode, CDK_PKT_SECRET_KEY);
2061 if (r_is_sk)
2062 *r_is_sk = pkt ? 1 : 0;
2063 }
2064 return pkt;
2065}
2066
2067
2068/* Return 1 if the is allowd in a key node. */
2069static int
2070is_key_node (cdk_kbnode_t node)
2071{
2072 switch (node->pkt->pkttype)
2073 {
2074 case CDK_PKT_SIGNATURE:
2075 case CDK_PKT_SECRET_KEY:
2076 case CDK_PKT_PUBLIC_KEY:
2077 case CDK_PKT_SECRET_SUBKEY:
2078 case CDK_PKT_PUBLIC_SUBKEY:
2079 case CDK_PKT_USER_ID:
2080 case CDK_PKT_ATTRIBUTE:
2081 return 1;
2082
2083 default:
2084 return 0;
2085 }
2086
2087 return 0;
2088}
2089
2090
2091cdk_error_t
2092cdk_keydb_import (cdk_keydb_hd_t hd, cdk_kbnode_t knode)
2093{
2094 cdk_kbnode_t node, chk;
2095 cdk_packet_t pkt;
2096 cdk_stream_t out;
2097 cdk_error_t rc;
2098 u32 keyid[2];
2099
2100 if (!hd || !knode)
2101 {
2102 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2102); } while(0);
;
2103 return CDK_Inv_Value;
2104 }
2105
2106 pkt = find_key_packet (knode, NULL((void*)0));
2107 if (!pkt)
2108 {
2109 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2109); } while(0);
;
2110 return CDK_Inv_Packet;
2111 }
2112
2113 _cdk_pkt_get_keyid (pkt, keyid);
2114 chk = NULL((void*)0);
2115 cdk_keydb_get_bykeyid (hd, keyid, &chk);
2116 if (chk)
2117 { /* FIXME: search for new signatures */
2118 cdk_kbnode_release (chk);
2119 return 0;
2120 }
2121
2122 /* We append data to the stream so we need to close
2123 the stream here to re-open it later. */
2124 if (hd->fp)
2125 {
2126 cdk_stream_close (hd->fp);
2127 hd->fp = NULL((void*)0);
2128 }
2129
2130 rc = _cdk_stream_append (hd->name, &out);
2131 if (rc)
2132 {
2133 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2133); } while(0);
;
2134 return rc;
2135 }
2136
2137 for (node = knode; node; node = node->next)
2138 {
2139 if (node->pkt->pkttype == CDK_PKT_RING_TRUST)
2140 continue; /* No uniformed syntax for this packet */
2141 if (node->pkt->pkttype == CDK_PKT_SIGNATURE &&
2142 !node->pkt->pkt.signature->flags.exportable)
2143 {
2144 _cdk_log_debug ("key db import: skip local signature\n")do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "key db import: skip local signature\n"); } while(0)
;
2145 continue;
2146 }
2147
2148 if (!is_key_node (node))
2149 {
2150 _cdk_log_debug ("key db import: skip invalid node of type %d\n",do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "key db import: skip invalid node of type %d\n", node->
pkt->pkttype); } while(0)
2151 node->pkt->pkttype)do { if (__builtin_expect((_gnutls_log_level >= 9), 0)) _gnutls_log
( 9, "key db import: skip invalid node of type %d\n", node->
pkt->pkttype); } while(0)
;
2152 continue;
2153 }
2154
2155 rc = cdk_pkt_write (out, node->pkt);
2156 if (rc)
2157 {
2158 cdk_stream_close (out);
2159 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2159); } while(0);
;
2160 return rc;
2161 }
2162 }
2163
2164 cdk_stream_close (out);
2165 hd->stats.new_keys++;
2166
2167 return 0;
2168}
2169
2170
2171cdk_error_t
2172_cdk_keydb_check_userid (cdk_keydb_hd_t hd, u32 * keyid, const char *id)
2173{
2174 cdk_kbnode_t knode = NULL((void*)0), unode = NULL((void*)0);
2175 cdk_error_t rc;
2176 int check;
2177 cdk_keydb_search_t st;
2178
2179 if (!hd)
2180 {
2181 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2181); } while(0);
;
2182 return CDK_Inv_Value;
2183 }
2184
2185 rc = cdk_keydb_search_start (&st, hd, CDK_DBSEARCH_KEYID, keyid);
2186 if (rc)
2187 {
2188 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2188); } while(0);
;
2189 return rc;
2190 }
2191 rc = cdk_keydb_search (st, hd, &knode);
2192 cdk_keydb_search_release (st);
2193
2194 if (rc)
2195 {
2196 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2196); } while(0);
;
2197 return rc;
2198 }
2199
2200 rc = cdk_keydb_search_start (&st, hd, CDK_DBSEARCH_EXACT, (char *) id);
2201 if (!rc)
2202 {
2203 rc = cdk_keydb_search (st, hd, &unode);
2204 cdk_keydb_search_release (st);
2205 }
2206 if (rc)
2207 {
2208 cdk_kbnode_release (knode);
2209 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2209); } while(0);
;
2210 return rc;
2211 }
2212
2213 check = 0;
2214 cdk_keydb_search_start (&st, hd, CDK_DBSEARCH_KEYID, keyid);
2215 if (unode && find_by_keyid (unode, st))
2216 check++;
2217 cdk_keydb_search_release (st);
2218 cdk_kbnode_release (unode);
2219
2220 cdk_keydb_search_start (&st, hd, CDK_DBSEARCH_EXACT, (char *) id);
2221 if (knode && find_by_pattern (knode, st))
2222 check++;
2223 cdk_keydb_search_release (st);
2224 cdk_kbnode_release (knode);
2225
2226 return check == 2 ? 0 : CDK_Inv_Value;
2227}
2228
2229
2230/**
2231 * cdk_keydb_check_sk:
2232 * @hd: the key db handle
2233 * @keyid: the 64-bit keyid
2234 *
2235 * Check if a secret key with the given key ID is available
2236 * in the key database.
2237 **/
2238cdk_error_t
2239cdk_keydb_check_sk (cdk_keydb_hd_t hd, u32 * keyid)
2240{
2241 cdk_stream_t db;
2242 cdk_packet_t pkt;
2243 cdk_error_t rc;
2244 u32 kid[2];
2245
2246 if (!hd || !keyid)
2247 {
2248 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2248); } while(0);
;
2249 return CDK_Inv_Value;
2250 }
2251 if (!hd->secret)
2252 {
2253 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2253); } while(0);
;
2254 return CDK_Inv_Mode;
2255 }
2256
2257 rc = _cdk_keydb_open (hd, &db);
2258 if (rc)
2259 {
2260 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2260); } while(0);
;
2261 return rc;
2262 }
2263 cdk_pkt_new (&pkt);
2264 while (!cdk_pkt_read (db, pkt))
2265 {
2266 if (pkt->pkttype != CDK_PKT_SECRET_KEY &&
2267 pkt->pkttype != CDK_PKT_SECRET_SUBKEY)
2268 {
2269 cdk_pkt_free (pkt);
2270 continue;
2271 }
2272 cdk_sk_get_keyid (pkt->pkt.secret_key, kid);
2273 if (KEYID_CMP (kid, keyid)((kid[0]) == (keyid[0]) && (kid[1]) == (keyid[1])))
2274 {
2275 cdk_pkt_release (pkt);
2276 return 0;
2277 }
2278 cdk_pkt_free (pkt);
2279 }
2280 cdk_pkt_release (pkt);
2281 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2281); } while(0);
;
2282 return CDK_Error_No_Key;
2283}
2284
2285
2286/**
2287 * cdk_listkey_start:
2288 * @r_ctx: pointer to store the new context
2289 * @db: the key database handle
2290 * @patt: string pattern
2291 * @fpatt: recipients from a stringlist to show
2292 *
2293 * Prepare a key listing with the given parameters. Two modes are supported.
2294 * The first mode uses string pattern to determine if the key should be
2295 * returned or not. The other mode uses a string list to request the key
2296 * which should be listed.
2297 **/
2298cdk_error_t
2299cdk_listkey_start (cdk_listkey_t * r_ctx, cdk_keydb_hd_t db,
2300 const char *patt, cdk_strlist_t fpatt)
2301{
2302 cdk_listkey_t ctx;
2303 cdk_stream_t inp;
2304 cdk_error_t rc;
2305
2306 if (!r_ctx || !db)
2307 {
2308 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2308); } while(0);
;
2309 return CDK_Inv_Value;
2310 }
2311 if ((patt && fpatt) || (!patt && !fpatt))
2312 {
2313 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2313); } while(0);
;
2314 return CDK_Inv_Mode;
2315 }
2316 rc = _cdk_keydb_open (db, &inp);
2317 if (rc)
2318 {
2319 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2319); } while(0);
;
2320 return rc;
2321 }
2322 ctx = cdk_callocgnutls_calloc (1, sizeof *ctx);
2323 if (!ctx)
2324 {
2325 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2325); } while(0);
;
2326 return CDK_Out_Of_Core;
2327 }
2328 ctx->db = db;
2329 ctx->inp = inp;
2330 if (patt)
2331 {
2332 ctx->u.patt = cdk_strdupgnutls_strdup (patt);
2333 if (!ctx->u.patt)
2334 {
2335 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2335); } while(0);
;
2336 return CDK_Out_Of_Core;
2337 }
2338 }
2339 else if (fpatt)
2340 {
2341 cdk_strlist_t l;
2342 for (l = fpatt; l; l = l->next)
2343 cdk_strlist_add (&ctx->u.fpatt, l->d);
2344 }
2345 ctx->type = patt ? 1 : 0;
2346 ctx->init = 1;
2347 *r_ctx = ctx;
2348 return 0;
2349}
2350
2351
2352/**
2353 * cdk_listkey_close:
2354 * @ctx: the list key context
2355 *
2356 * Free the list key context.
2357 **/
2358void
2359cdk_listkey_close (cdk_listkey_t ctx)
2360{
2361 if (!ctx)
2362 return;
2363
2364 if (ctx->type)
2365 cdk_freegnutls_free (ctx->u.patt);
2366 else
2367 cdk_strlist_free (ctx->u.fpatt);
2368 cdk_freegnutls_free (ctx);
2369}
2370
2371
2372/**
2373 * cdk_listkey_next:
2374 * @ctx: list key context
2375 * @r_key: the pointer to the new key node object
2376 *
2377 * Retrieve the next key from the pattern of the key list context.
2378 **/
2379cdk_error_t
2380cdk_listkey_next (cdk_listkey_t ctx, cdk_kbnode_t * ret_key)
2381{
2382 if (!ctx || !ret_key)
2383 {
2384 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2384); } while(0);
;
2385 return CDK_Inv_Value;
2386 }
2387 if (!ctx->init)
2388 {
2389 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2389); } while(0);
;
2390 return CDK_Inv_Mode;
2391 }
2392
2393 if (ctx->type && ctx->u.patt[0] == '*')
2394 return cdk_keydb_get_keyblock (ctx->inp, ret_key);
2395 else if (ctx->type)
2396 {
2397 cdk_kbnode_t node;
2398 struct cdk_keydb_search_s ks;
2399 cdk_error_t rc;
2400
2401 for (;;)
2402 {
2403 rc = cdk_keydb_get_keyblock (ctx->inp, &node);
2404 if (rc)
2405 {
2406 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2406); } while(0);
;
2407 return rc;
2408 }
2409 memset (&ks, 0, sizeof (ks));
2410 ks.type = CDK_DBSEARCH_SUBSTR;
2411 ks.u.pattern = ctx->u.patt;
2412 if (find_by_pattern (node, &ks))
2413 {
2414 *ret_key = node;
2415 return 0;
2416 }
2417 cdk_kbnode_release (node);
2418 node = NULL((void*)0);
2419 }
2420 }
2421 else
2422 {
2423 if (!ctx->t)
2424 ctx->t = ctx->u.fpatt;
2425 else if (ctx->t->next)
2426 ctx->t = ctx->t->next;
2427 else
2428 return CDK_EOF;
2429 return cdk_keydb_get_bypattern (ctx->db, ctx->t->d, ret_key);
2430 }
2431 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "keydb.c",2431); } while(0);
;
2432 return CDK_General_Error;
2433}
2434
2435
2436int
2437_cdk_keydb_is_secret (cdk_keydb_hd_t db)
2438{
2439 return db->secret;
2440}