1 /* keydb.c - Key database routines
2 * Copyright (C) 2002-2012 Free Software Foundation, Inc.
6 * This file is part of OpenCDK.
8 * The OpenCDK library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
39 #define KEYID_CMP(a, b) ((a[0]) == (b[0]) && (a[1]) == (b[1]))
40 #define KEYDB_CACHE_ENTRIES 8
42 static void keydb_cache_free (key_table_t cache
);
43 static int classify_data (const byte
* buf
, size_t len
);
44 static cdk_kbnode_t
find_selfsig_node (cdk_kbnode_t key
, cdk_pkt_pubkey_t pk
);
47 keydb_idx_mkname (const char *file
)
49 static const char *fmt
= "%s.idx";
51 size_t len
= strlen (file
) + strlen (fmt
);
53 fname
= cdk_calloc (1, len
+ 1);
56 if (snprintf (fname
, len
, fmt
, file
) <= 0)
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:
66 4 octets offset of the packet
70 We store the keyid and the fingerprint due to the fact we can't get
71 the keyid from a v3 fingerprint directly.
74 keydb_idx_build (const char *file
)
77 cdk_stream_t inp
, out
= NULL
;
78 byte buf
[4 + 8 + KEY_FPR_LEN
];
89 rc
= cdk_stream_open (file
, &inp
);
96 idx_name
= keydb_idx_mkname (file
);
99 cdk_stream_close (inp
);
101 return CDK_Out_Of_Core
;
103 rc
= cdk_stream_create (idx_name
, &out
);
107 cdk_stream_close (inp
);
113 while (!cdk_stream_eof (inp
))
115 off_t pos
= cdk_stream_tell (inp
);
117 rc
= cdk_pkt_read (inp
, pkt
);
120 _cdk_log_debug ("index build failed packet off=%lu\n", (unsigned long)pos
);
121 /* FIXME: The index is incomplete */
124 if (pkt
->pkttype
== CDK_PKT_PUBLIC_KEY
||
125 pkt
->pkttype
== CDK_PKT_PUBLIC_SUBKEY
)
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_LEN
);
137 cdk_pkt_release (pkt
);
139 cdk_stream_close (out
);
140 cdk_stream_close (inp
);
147 * cdk_keydb_idx_rebuild:
148 * @hd: key database handle
150 * Rebuild the key index files for the given key database.
153 cdk_keydb_idx_rebuild (cdk_keydb_hd_t db
, cdk_keydb_search_t dbs
)
160 if (!db
|| !db
->name
|| !dbs
)
163 return CDK_Inv_Value
;
168 tmp_idx_name
= keydb_idx_mkname (db
->name
);
172 return CDK_Out_Of_Core
;
174 err
= stat (tmp_idx_name
, &stbuf
);
175 cdk_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. */
181 cdk_stream_close (dbs
->idx
);
185 dbs
->idx_name
= keydb_idx_mkname (db
->name
);
189 return CDK_Out_Of_Core
;
192 rc
= keydb_idx_build (db
->name
);
194 rc
= cdk_stream_open (dbs
->idx_name
, &dbs
->idx
);
202 keydb_idx_parse (cdk_stream_t inp
, key_idx_t
* r_idx
)
210 return CDK_Inv_Value
;
213 idx
= cdk_calloc (1, sizeof *idx
);
217 return CDK_Out_Of_Core
;
220 while (!cdk_stream_eof (inp
))
222 if (cdk_stream_read (inp
, buf
, 4) == CDK_EOF
)
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_LEN
);
233 return cdk_stream_eof (inp
) ? CDK_EOF
: 0;
238 keydb_idx_search (cdk_stream_t inp
, u32
* keyid
, const byte
* fpr
,
246 return CDK_Inv_Value
;
248 if ((keyid
&& fpr
) || (!keyid
&& !fpr
))
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. */
258 cdk_stream_seek (inp
, 0);
259 while (keydb_idx_parse (inp
, &idx
) != CDK_EOF
)
261 if (keyid
&& KEYID_CMP (keyid
, idx
->keyid
))
263 *r_off
= idx
->offset
;
266 else if (fpr
&& !memcmp (idx
->fpr
, fpr
, KEY_FPR_LEN
))
268 *r_off
= idx
->offset
;
275 return *r_off
!= 0xFFFFFFFF ? 0 : CDK_EOF
;
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.
287 * Create a new keyring db handle from the contents of a buffer.
290 cdk_keydb_new_from_mem (cdk_keydb_hd_t
* r_db
, int secret
, int armor
,
291 const void *data
, size_t datlen
)
299 return CDK_Inv_Value
;
302 db
= calloc (1, sizeof *db
);
303 rc
= cdk_stream_tmp_from_mem (data
, datlen
, &db
->fp
);
312 cdk_stream_set_armor_flag (db
->fp
, 0);
313 db
->type
= CDK_DBTYPE_DATA
;
321 * @hd: the keydb object
323 * Free the keydb object.
326 cdk_keydb_free (cdk_keydb_hd_t hd
)
337 if (hd
->fp
&& !hd
->fp_ref
)
339 cdk_stream_close (hd
->fp
);
351 _cdk_keydb_open (cdk_keydb_hd_t hd
, cdk_stream_t
* ret_kr
)
359 return CDK_Inv_Value
;
363 if ((hd
->type
== CDK_DBTYPE_DATA
)
367 cdk_stream_seek (kr
, 0);
369 else if (hd
->type
== CDK_DBTYPE_PK_KEYRING
||
370 hd
->type
== CDK_DBTYPE_SK_KEYRING
)
372 rc
= cdk_stream_open (hd
->name
, &kr
);
391 find_by_keyid (cdk_kbnode_t knode
, cdk_keydb_search_t ks
)
396 for (node
= knode
; node
; node
= node
->next
)
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
)
403 _cdk_pkt_get_keyid (node
->pkt
, keyid
);
406 case CDK_DBSEARCH_SHORT_KEYID
:
407 if (keyid
[1] == ks
->u
.keyid
[1])
411 case CDK_DBSEARCH_KEYID
:
412 if (KEYID_CMP (keyid
, ks
->u
.keyid
))
417 _cdk_log_debug ("find_by_keyid: invalid mode = %d\n", ks
->type
);
427 find_by_fpr (cdk_kbnode_t knode
, cdk_keydb_search_t ks
)
430 byte fpr
[KEY_FPR_LEN
];
432 if (ks
->type
!= CDK_DBSEARCH_FPR
)
435 for (node
= knode
; node
; node
= node
->next
)
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
)
442 _cdk_pkt_get_fingerprint (node
->pkt
, fpr
);
443 if (!memcmp (ks
->u
.fpr
, fpr
, KEY_FPR_LEN
))
454 find_by_pattern (cdk_kbnode_t knode
, cdk_keydb_search_t ks
)
460 for (node
= knode
; node
; node
= node
->next
)
462 if (node
->pkt
->pkttype
!= CDK_PKT_USER_ID
)
464 if (node
->pkt
->pkt
.user_id
->attrib_img
!= NULL
)
465 continue; /* Skip attribute packets. */
466 uidlen
= node
->pkt
->pkt
.user_id
->len
;
467 name
= node
->pkt
->pkt
.user_id
->name
;
470 case CDK_DBSEARCH_EXACT
:
472 (strlen (ks
->u
.pattern
) == uidlen
&&
473 !strncmp (ks
->u
.pattern
, name
, uidlen
)))
477 case CDK_DBSEARCH_SUBSTR
:
480 if (name
&& strlen (ks
->u
.pattern
) > uidlen
)
482 if (name
&& _cdk_memistr (name
, uidlen
, ks
->u
.pattern
))
486 default: /* Invalid mode */
495 keydb_cache_free (key_table_t cache
)
510 keydb_cache_find (cdk_keydb_search_t desc
)
512 key_table_t cache
= desc
->cache
;
515 for (t
= cache
; t
; t
= t
->next
)
519 case CDK_DBSEARCH_SHORT_KEYID
:
520 case CDK_DBSEARCH_KEYID
:
521 if (KEYID_CMP (desc
->u
.keyid
, desc
->u
.keyid
))
525 case CDK_DBSEARCH_EXACT
:
526 if (strlen (desc
->u
.pattern
) == strlen (desc
->u
.pattern
) &&
527 !strcmp (desc
->u
.pattern
, desc
->u
.pattern
))
531 case CDK_DBSEARCH_SUBSTR
:
532 if (strstr (desc
->u
.pattern
, desc
->u
.pattern
))
536 case CDK_DBSEARCH_FPR
:
537 if (!memcmp (desc
->u
.fpr
, desc
->u
.fpr
, KEY_FPR_LEN
))
548 keydb_cache_add (cdk_keydb_search_t dbs
, off_t offset
)
552 if (dbs
->ncache
> KEYDB_CACHE_ENTRIES
)
553 return 0; /* FIXME: we should replace the last entry. */
554 k
= cdk_calloc (1, sizeof *k
);
558 return CDK_Out_Of_Core
;
563 k
->next
= dbs
->cache
;
566 _cdk_log_debug ("cache: add entry off=%d type=%d\n", (int) offset
,
572 idx_init (cdk_keydb_hd_t db
, cdk_keydb_search_t dbs
)
574 cdk_error_t ec
, rc
= 0;
576 if (cdk_stream_get_length (db
->fp
) < 524288)
582 dbs
->idx_name
= keydb_idx_mkname (db
->name
);
585 rc
= CDK_Out_Of_Core
;
588 ec
= cdk_stream_open (dbs
->idx_name
, &dbs
->idx
);
590 if (ec
&& !db
->secret
)
592 rc
= keydb_idx_build (db
->name
);
594 rc
= cdk_stream_open (dbs
->idx_name
, &dbs
->idx
);
597 _cdk_log_debug ("create key index table\n");
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
);
616 * cdk_keydb_search_start:
618 * @db: key database handle
619 * @type: specifies the search type
620 * @desc: description which depends on the type
622 * Create a new keydb search object.
625 cdk_keydb_search_start (cdk_keydb_search_t
* st
, cdk_keydb_hd_t db
, int type
,
636 return CDK_Inv_Value
;
638 if (type
!= CDK_DBSEARCH_NEXT
&& !desc
)
644 *st
= cdk_calloc (1, sizeof (cdk_keydb_search_s
));
648 return CDK_Out_Of_Core
;
651 rc
= idx_init (db
, *st
);
652 if (rc
!= CDK_Success
)
662 case CDK_DBSEARCH_EXACT
:
663 case CDK_DBSEARCH_SUBSTR
:
664 cdk_free ((*st
)->u
.pattern
);
665 (*st
)->u
.pattern
= cdk_strdup (desc
);
666 if (!(*st
)->u
.pattern
)
670 return CDK_Out_Of_Core
;
674 case CDK_DBSEARCH_SHORT_KEYID
:
676 (*st
)->u
.keyid
[1] = keyid
[0];
679 case CDK_DBSEARCH_KEYID
:
681 (*st
)->u
.keyid
[0] = keyid
[0];
682 (*st
)->u
.keyid
[1] = keyid
[1];
685 case CDK_DBSEARCH_FPR
:
686 memcpy ((*st
)->u
.fpr
, desc
, KEY_FPR_LEN
);
689 case CDK_DBSEARCH_NEXT
:
692 case CDK_DBSEARCH_AUTO
:
693 /* Override the type with the actual db search type. */
694 (*st
)->type
= classify_data (desc
, strlen (desc
));
697 case CDK_DBSEARCH_SUBSTR
:
698 case CDK_DBSEARCH_EXACT
:
699 cdk_free ((*st
)->u
.pattern
);
700 p
= (*st
)->u
.pattern
= cdk_strdup (desc
);
705 return CDK_Out_Of_Core
;
709 case CDK_DBSEARCH_SHORT_KEYID
:
710 case CDK_DBSEARCH_KEYID
:
712 if (!strncmp (p
, "0x", 2))
716 (*st
)->u
.keyid
[0] = 0;
717 (*st
)->u
.keyid
[1] = strtoul (p
, NULL
, 16);
719 else if (strlen (p
) == 16)
721 (*st
)->u
.keyid
[0] = strtoul (p
, NULL
, 16);
722 (*st
)->u
.keyid
[1] = strtoul (p
+ 8, NULL
, 16);
725 { /* Invalid key ID object. */
732 case CDK_DBSEARCH_FPR
:
734 if (strlen (p
) != 2 * KEY_FPR_LEN
)
740 for (i
= 0; i
< KEY_FPR_LEN
; i
++)
743 tmp
[1] = p
[2 * i
+ 1];
745 (*st
)->u
.fpr
[i
] = strtoul (tmp
, NULL
, 16);
753 _cdk_log_debug ("cdk_keydb_search_start: invalid mode = %d\n", type
);
763 keydb_pos_from_cache (cdk_keydb_hd_t hd
, cdk_keydb_search_t ks
,
764 int *r_cache_hit
, off_t
* r_off
)
768 if (!hd
|| !r_cache_hit
|| !r_off
)
771 return CDK_Inv_Value
;
774 /* Reset the values. */
778 c
= keydb_cache_find (ks
);
781 _cdk_log_debug ("cache: found entry in cache.\n");
787 /* No index cache available so we just return here. */
793 if (ks
->type
== CDK_DBSEARCH_KEYID
)
795 if (keydb_idx_search (ks
->idx
, ks
->u
.keyid
, NULL
, r_off
))
798 return CDK_Error_No_Key
;
800 _cdk_log_debug ("cache: found keyid entry in idx table.\n");
803 else if (ks
->type
== CDK_DBSEARCH_FPR
)
805 if (keydb_idx_search (ks
->idx
, NULL
, ks
->u
.fpr
, r_off
))
808 return CDK_Error_No_Key
;
810 _cdk_log_debug ("cache: found fpr entry in idx table.\n");
819 cdk_keydb_search_release (cdk_keydb_search_t st
)
821 keydb_cache_free (st
->cache
);
824 cdk_stream_close (st
->idx
);
828 if (st
->type
== CDK_DBSEARCH_EXACT
|| st
->type
== CDK_DBSEARCH_SUBSTR
)
829 cdk_free (st
->u
.pattern
);
836 * @st: the search handle
837 * @hd: the keydb object
838 * @ret_key: kbnode object to store the key
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.
844 cdk_keydb_search (cdk_keydb_search_t st
, cdk_keydb_hd_t hd
,
845 cdk_kbnode_t
* ret_key
)
850 off_t pos
= 0, off
= 0;
851 int key_found
= 0, cache_hit
= 0;
853 if (!hd
|| !ret_key
|| !st
)
856 return CDK_Inv_Value
;
862 rc
= _cdk_keydb_open (hd
, &kr
);
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
);
881 while (!key_found
&& !rc
)
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
);
888 pos
= cdk_stream_tell (kr
);
890 rc
= cdk_keydb_get_keyblock (kr
, &knode
);
905 case CDK_DBSEARCH_SHORT_KEYID
:
906 case CDK_DBSEARCH_KEYID
:
907 key_found
= find_by_keyid (knode
, st
);
910 case CDK_DBSEARCH_FPR
:
911 key_found
= find_by_fpr (knode
, st
);
914 case CDK_DBSEARCH_EXACT
:
915 case CDK_DBSEARCH_SUBSTR
:
916 key_found
= find_by_pattern (knode
, st
);
919 case CDK_DBSEARCH_NEXT
:
920 st
->off
= cdk_stream_tell (kr
);
921 key_found
= knode
? 1 : 0;
927 if (!keydb_cache_find (st
))
928 keydb_cache_add (st
, pos
);
932 cdk_kbnode_release (knode
);
936 if (key_found
&& rc
== CDK_EOF
)
938 else if (rc
== CDK_EOF
&& !key_found
)
941 rc
= CDK_Error_No_Key
;
943 *ret_key
= key_found
? knode
: NULL
;
948 cdk_keydb_get_bykeyid (cdk_keydb_hd_t hd
, u32
* keyid
, cdk_kbnode_t
* ret_key
)
951 cdk_keydb_search_t st
;
953 if (!hd
|| !keyid
|| !ret_key
)
956 return CDK_Inv_Value
;
959 rc
= cdk_keydb_search_start (&st
, hd
, CDK_DBSEARCH_KEYID
, keyid
);
961 rc
= cdk_keydb_search (st
, hd
, ret_key
);
963 cdk_keydb_search_release (st
);
969 cdk_keydb_get_byfpr (cdk_keydb_hd_t hd
, const byte
* fpr
,
970 cdk_kbnode_t
* r_key
)
973 cdk_keydb_search_t st
;
975 if (!hd
|| !fpr
|| !r_key
)
978 return CDK_Inv_Value
;
981 rc
= cdk_keydb_search_start (&st
, hd
, CDK_DBSEARCH_FPR
, (byte
*) fpr
);
983 rc
= cdk_keydb_search (st
, hd
, r_key
);
985 cdk_keydb_search_release (st
);
991 cdk_keydb_get_bypattern (cdk_keydb_hd_t hd
, const char *patt
,
992 cdk_kbnode_t
* ret_key
)
995 cdk_keydb_search_t st
;
997 if (!hd
|| !patt
|| !ret_key
)
1000 return CDK_Inv_Value
;
1003 rc
= cdk_keydb_search_start (&st
, hd
, CDK_DBSEARCH_SUBSTR
, (char *) patt
);
1005 rc
= cdk_keydb_search (st
, hd
, ret_key
);
1010 cdk_keydb_search_release (st
);
1016 keydb_check_key (cdk_packet_t pkt
)
1018 cdk_pkt_pubkey_t pk
;
1021 if (pkt
->pkttype
== CDK_PKT_PUBLIC_KEY
||
1022 pkt
->pkttype
== CDK_PKT_PUBLIC_SUBKEY
)
1024 pk
= pkt
->pkt
.public_key
;
1027 else if (pkt
->pkttype
== CDK_PKT_SECRET_KEY
||
1028 pkt
->pkttype
== CDK_PKT_SECRET_SUBKEY
)
1030 pk
= pkt
->pkt
.secret_key
->pk
;
1033 else /* No key object. */
1035 valid
= !pk
->is_revoked
&& !pk
->has_expired
;
1038 return valid
&& !pk
->is_invalid
;
1042 /* Find the first kbnode with the requested packet type
1043 that represents a valid key. */
1045 kbnode_find_valid (cdk_kbnode_t root
, cdk_packet_type_t pkttype
)
1049 for (n
= root
; n
; n
= n
->next
)
1051 if (n
->pkt
->pkttype
!= pkttype
)
1053 if (keydb_check_key (n
->pkt
))
1062 keydb_find_byusage (cdk_kbnode_t root
, int req_usage
, int is_pk
)
1064 cdk_kbnode_t node
, key
;
1068 req_type
= is_pk
? CDK_PKT_PUBLIC_KEY
: CDK_PKT_SECRET_KEY
;
1070 return kbnode_find_valid (root
, req_type
);
1072 node
= cdk_kbnode_find (root
, req_type
);
1073 if (node
&& !keydb_check_key (node
->pkt
))
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
)
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
))
1088 if (node
->pkt
->pkt
.public_key
->timestamp
> timestamp
)
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
))
1096 if (node
->pkt
->pkt
.secret_key
->pk
->timestamp
> timestamp
)
1106 keydb_find_bykeyid (cdk_kbnode_t root
, const u32
* keyid
, int search_mode
)
1111 for (node
= root
; node
; node
= node
->next
)
1113 if (!_cdk_pkt_get_keyid (node
->pkt
, kid
))
1115 if (search_mode
== CDK_DBSEARCH_SHORT_KEYID
&& kid
[1] == keyid
[1])
1117 else if (kid
[0] == keyid
[0] && kid
[1] == keyid
[1])
1125 _cdk_keydb_get_sk_byusage (cdk_keydb_hd_t hd
, const char *name
,
1126 cdk_seckey_t
* ret_sk
, int usage
)
1128 cdk_kbnode_t knode
= NULL
;
1129 cdk_kbnode_t node
, sk_node
, pk_node
;
1130 cdk_pkt_seckey_t sk
;
1134 cdk_keydb_search_t st
;
1136 if (!ret_sk
|| !usage
)
1139 return CDK_Inv_Value
;
1145 return CDK_Error_No_Keyring
;
1149 rc
= cdk_keydb_search_start (&st
, hd
, CDK_DBSEARCH_AUTO
, (char *) name
);
1156 rc
= cdk_keydb_search (st
, hd
, &knode
);
1163 cdk_keydb_search_release (st
);
1165 sk_node
= keydb_find_byusage (knode
, usage
, 0);
1168 cdk_kbnode_release (knode
);
1170 return CDK_Unusable_Key
;
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
;
1178 for (node
= knode
; node
; node
= node
->next
)
1180 if (node
->pkt
->pkttype
== CDK_PKT_USER_ID
)
1182 s
= node
->pkt
->pkt
.user_id
->name
;
1183 if (sk
&& !sk
->pk
->uid
&& _cdk_memistr (s
, strlen (s
), name
))
1185 _cdk_copy_userid (&sk
->pk
->uid
, node
->pkt
->pkt
.user_id
);
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
);
1196 cdk_kbnode_release (knode
);
1198 return CDK_Unusable_Key
;
1200 node
= find_selfsig_node (knode
, pk_node
->pkt
->pkt
.secret_key
->pk
);
1201 if (sk
&& sk
->pk
&& sk
->pk
->uid
&& node
)
1202 _cdk_copy_signature (&sk
->pk
->uid
->selfsig
, node
->pkt
->pkt
.signature
);
1204 /* We only release the outer packet. */
1205 _cdk_pkt_detach_free (sk_node
->pkt
, &pkttype
, (void *) &sk
);
1206 cdk_kbnode_release (knode
);
1213 _cdk_keydb_get_pk_byusage (cdk_keydb_hd_t hd
, const char *name
,
1214 cdk_pubkey_t
* ret_pk
, int usage
)
1216 cdk_kbnode_t knode
, node
, pk_node
;
1217 cdk_pkt_pubkey_t pk
;
1220 cdk_keydb_search_t st
;
1222 if (!ret_pk
|| !usage
)
1225 return CDK_Inv_Value
;
1230 return CDK_Error_No_Keyring
;
1234 rc
= cdk_keydb_search_start (&st
, hd
, CDK_DBSEARCH_AUTO
, (char *) name
);
1236 rc
= cdk_keydb_search (st
, hd
, &knode
);
1243 cdk_keydb_search_release (st
);
1245 node
= keydb_find_byusage (knode
, usage
, 1);
1248 cdk_kbnode_release (knode
);
1250 return CDK_Unusable_Key
;
1254 _cdk_copy_pubkey (&pk
, node
->pkt
->pkt
.public_key
);
1255 for (node
= knode
; node
; node
= node
->next
)
1257 if (node
->pkt
->pkttype
== CDK_PKT_USER_ID
)
1259 s
= node
->pkt
->pkt
.user_id
->name
;
1260 if (pk
&& !pk
->uid
&& _cdk_memistr (s
, strlen (s
), name
))
1262 _cdk_copy_userid (&pk
->uid
, node
->pkt
->pkt
.user_id
);
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
);
1273 cdk_kbnode_release (knode
);
1275 return CDK_Unusable_Key
;
1277 node
= find_selfsig_node (knode
, pk_node
->pkt
->pkt
.public_key
);
1278 if (pk
&& pk
->uid
&& node
)
1279 _cdk_copy_signature (&pk
->uid
->selfsig
, node
->pkt
->pkt
.signature
);
1280 cdk_kbnode_release (knode
);
1289 * @hd: key db handle
1290 * @keyid: keyid of the key
1291 * @r_pk: the allocated public key
1293 * Perform a key database search by keyid and return the raw public
1294 * key without any signatures or user id's.
1297 cdk_keydb_get_pk (cdk_keydb_hd_t hd
, u32
* keyid
, cdk_pubkey_t
* r_pk
)
1299 cdk_kbnode_t knode
= NULL
, node
;
1304 cdk_keydb_search_t st
;
1306 if (!keyid
|| !r_pk
)
1309 return CDK_Inv_Value
;
1314 return CDK_Error_No_Keyring
;
1318 s_type
= !keyid
[0] ? CDK_DBSEARCH_SHORT_KEYID
: CDK_DBSEARCH_KEYID
;
1319 rc
= cdk_keydb_search_start (&st
, hd
, s_type
, keyid
);
1325 rc
= cdk_keydb_search (st
, hd
, &knode
);
1326 cdk_keydb_search_release (st
);
1333 node
= keydb_find_bykeyid (knode
, keyid
, s_type
);
1336 cdk_kbnode_release (knode
);
1338 return CDK_Error_No_Key
;
1341 /* See comment in cdk_keydb_get_sk() */
1342 _cdk_pkt_detach_free (node
->pkt
, &pkttype
, (void *) &pk
);
1344 _cdk_kbnode_clone (node
);
1345 cdk_kbnode_release (knode
);
1353 * @hd: key db handle
1354 * @keyid: the keyid of the key
1355 * @ret_sk: the allocated secret key
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.
1362 cdk_keydb_get_sk (cdk_keydb_hd_t hd
, u32
* keyid
, cdk_seckey_t
* ret_sk
)
1364 cdk_kbnode_t snode
, node
;
1369 if (!keyid
|| !ret_sk
)
1372 return CDK_Inv_Value
;
1377 return CDK_Error_No_Keyring
;
1381 rc
= cdk_keydb_get_bykeyid (hd
, keyid
, &snode
);
1388 node
= keydb_find_bykeyid (snode
, keyid
, CDK_DBSEARCH_KEYID
);
1391 cdk_kbnode_release (snode
);
1393 return CDK_Error_No_Key
;
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
);
1408 is_selfsig (cdk_kbnode_t node
, const u32
* keyid
)
1410 cdk_pkt_signature_t sig
;
1412 if (node
->pkt
->pkttype
!= CDK_PKT_SIGNATURE
)
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])
1423 /* Find the newest self signature for the public key @pk
1424 and return the signature node. */
1426 find_selfsig_node (cdk_kbnode_t key
, cdk_pkt_pubkey_t pk
)
1428 cdk_kbnode_t n
, sig
;
1432 cdk_pk_get_keyid (pk
, keyid
);
1435 for (n
= key
; n
; n
= n
->next
)
1437 if (is_selfsig (n
, keyid
) && n
->pkt
->pkt
.signature
->timestamp
> ts
)
1439 ts
= n
->pkt
->pkt
.signature
->timestamp
;
1448 key_usage_to_cdk_usage (unsigned int usage
)
1450 unsigned key_usage
= 0;
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
;
1463 key_usage
|= CDK_KEY_USG_AUTH
;
1464 if (usage
& 0x80) /* encrypt comm. + storage */
1465 key_usage
|= CDK_KEY_USG_SHARED_KEY
;
1471 keydb_merge_selfsig (cdk_kbnode_t key
, u32
* keyid
)
1473 cdk_kbnode_t node
, kbnode
, unode
;
1474 cdk_subpkt_t s
= NULL
;
1475 cdk_pkt_signature_t sig
= NULL
;
1476 cdk_pkt_userid_t uid
= NULL
;
1477 const byte
*symalg
= NULL
, *hashalg
= NULL
, *compalg
= NULL
;
1478 size_t nsymalg
= 0, nhashalg
= 0, ncompalg
= 0, n
= 0;
1479 size_t key_expire
= 0;
1484 return CDK_Inv_Value
;
1487 for (node
= key
; node
; node
= node
->next
)
1489 if (!is_selfsig (node
, keyid
))
1491 unode
= cdk_kbnode_find_prev (key
, node
, CDK_PKT_USER_ID
);
1495 return CDK_Error_No_Key
;
1497 uid
= unode
->pkt
->pkt
.user_id
;
1498 sig
= node
->pkt
->pkt
.signature
;
1499 s
= cdk_subpkt_find (sig
->hashed
, CDK_SIGSUBPKT_PRIMARY_UID
);
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
);
1515 s
= cdk_subpkt_find (sig
->hashed
, CDK_SIGSUBPKT_PREFS_HASH
);
1522 s
= cdk_subpkt_find (sig
->hashed
, CDK_SIGSUBPKT_PREFS_ZIP
);
1529 if (uid
->prefs
!= NULL
)
1530 cdk_free (uid
->prefs
);
1531 if (!n
|| !hashalg
|| !compalg
|| !symalg
)
1535 uid
->prefs
= cdk_calloc (1, sizeof (*uid
->prefs
) * (n
+ 1));
1539 return CDK_Out_Of_Core
;
1542 for (; nsymalg
; nsymalg
--, n
++)
1544 uid
->prefs
[n
].type
= CDK_PREFTYPE_SYM
;
1545 uid
->prefs
[n
].value
= *symalg
++;
1547 for (; nhashalg
; nhashalg
--, n
++)
1549 uid
->prefs
[n
].type
= CDK_PREFTYPE_HASH
;
1550 uid
->prefs
[n
].value
= *hashalg
++;
1552 for (; ncompalg
; ncompalg
--, n
++)
1554 uid
->prefs
[n
].type
= CDK_PREFTYPE_ZIP
;
1555 uid
->prefs
[n
].value
= *compalg
++;
1558 uid
->prefs
[n
].type
= CDK_PREFTYPE_NONE
; /* end of list marker */
1559 uid
->prefs
[n
].value
= 0;
1560 uid
->prefs_size
= n
;
1564 /* Now we add the extracted information to the primary key. */
1565 kbnode
= cdk_kbnode_find (key
, CDK_PKT_PUBLIC_KEY
);
1568 cdk_pkt_pubkey_t pk
= kbnode
->pkt
->pkt
.public_key
;
1569 if (uid
&& uid
->prefs
&& n
)
1571 if (pk
->prefs
!= NULL
)
1572 cdk_free (pk
->prefs
);
1573 pk
->prefs
= _cdk_copy_prefs (uid
->prefs
);
1578 pk
->expiredate
= pk
->timestamp
+ key_expire
;
1579 pk
->has_expired
= pk
->expiredate
> (u32
) gnutls_time (NULL
) ? 0 : 1;
1590 keydb_parse_allsigs (cdk_kbnode_t knode
, cdk_keydb_hd_t hd
, int check
)
1592 cdk_kbnode_t node
, kb
;
1593 cdk_pkt_signature_t sig
;
1594 cdk_pkt_pubkey_t pk
;
1595 cdk_subpkt_t s
= NULL
;
1596 u32 expiredate
= 0, curtime
= (u32
) gnutls_time (NULL
);
1602 return CDK_Inv_Value
;
1607 return CDK_Inv_Mode
;
1610 kb
= cdk_kbnode_find (knode
, CDK_PKT_SECRET_KEY
);
1615 for (node
= knode
; node
; node
= node
->next
)
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;
1624 kb
= cdk_kbnode_find (knode
, CDK_PKT_PUBLIC_KEY
);
1628 return CDK_Wrong_Format
;
1630 cdk_pk_get_keyid (kb
->pkt
->pkt
.public_key
, keyid
);
1632 for (node
= knode
; node
; node
= node
->next
)
1634 if (node
->pkt
->pkttype
== CDK_PKT_SIGNATURE
)
1636 sig
= node
->pkt
->pkt
.signature
;
1637 /* Revocation certificates for primary keys */
1638 if (sig
->sig_class
== 0x20)
1640 kb
= cdk_kbnode_find_prev (knode
, node
, CDK_PKT_PUBLIC_KEY
);
1643 kb
->pkt
->pkt
.public_key
->is_revoked
= 1;
1645 _cdk_pk_check_sig (hd
, kb
, node
, NULL
, NULL
);
1650 return CDK_Error_No_Key
;
1653 /* Revocation certificates for subkeys */
1654 else if (sig
->sig_class
== 0x28)
1656 kb
= cdk_kbnode_find_prev (knode
, node
, CDK_PKT_PUBLIC_SUBKEY
);
1659 kb
->pkt
->pkt
.public_key
->is_revoked
= 1;
1661 _cdk_pk_check_sig (hd
, kb
, node
, NULL
, NULL
);
1666 return CDK_Error_No_Key
;
1669 /* Revocation certifcates for user ID's */
1670 else if (sig
->sig_class
== 0x30)
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
);
1677 kb
->pkt
->pkt
.user_id
->is_revoked
= 1;
1679 _cdk_pk_check_sig (hd
, kb
, node
, NULL
, NULL
);
1684 return CDK_Error_No_Key
;
1687 /* Direct certificates for primary keys */
1688 else if (sig
->sig_class
== 0x1F)
1690 kb
= cdk_kbnode_find_prev (knode
, node
, CDK_PKT_PUBLIC_KEY
);
1693 pk
= kb
->pkt
->pkt
.public_key
;
1695 s
= cdk_subpkt_find (node
->pkt
->pkt
.signature
->hashed
,
1696 CDK_SIGSUBPKT_KEY_EXPIRE
);
1699 expiredate
= _cdk_buftou32 (s
->d
);
1700 pk
->expiredate
= pk
->timestamp
+ expiredate
;
1701 pk
->has_expired
= pk
->expiredate
> curtime
? 0 : 1;
1704 _cdk_pk_check_sig (hd
, kb
, node
, NULL
, NULL
);
1709 return CDK_Error_No_Key
;
1712 /* Direct certificates for subkeys */
1713 else if (sig
->sig_class
== 0x18)
1715 kb
= cdk_kbnode_find_prev (knode
, node
, CDK_PKT_PUBLIC_SUBKEY
);
1718 pk
= kb
->pkt
->pkt
.public_key
;
1720 s
= cdk_subpkt_find (node
->pkt
->pkt
.signature
->hashed
,
1721 CDK_SIGSUBPKT_KEY_EXPIRE
);
1724 expiredate
= _cdk_buftou32 (s
->d
);
1725 pk
->expiredate
= pk
->timestamp
+ expiredate
;
1726 pk
->has_expired
= pk
->expiredate
> curtime
? 0 : 1;
1729 _cdk_pk_check_sig (hd
, kb
, node
, NULL
, NULL
);
1734 return CDK_Error_No_Key
;
1739 node
= cdk_kbnode_find (knode
, CDK_PKT_PUBLIC_KEY
);
1740 if (node
&& node
->pkt
->pkt
.public_key
->version
== 3)
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
)
1747 if (is_selfsig (node
, keyid
))
1754 if (node
&& (node
->pkt
->pkt
.public_key
->is_revoked
||
1755 node
->pkt
->pkt
.public_key
->has_expired
))
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
)
1761 if (node
->pkt
->pkttype
== CDK_PKT_PUBLIC_SUBKEY
)
1762 node
->pkt
->pkt
.public_key
->is_invalid
= 1;
1770 add_key_usage (cdk_kbnode_t knode
, u32 keyid
[2], unsigned int usage
)
1772 cdk_kbnode_t p
, ctx
;
1776 while ((p
= cdk_kbnode_walk (knode
, &ctx
, 0)))
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])
1784 pkt
->pkt
.public_key
->pubkey_usage
= usage
;
1792 cdk_keydb_get_keyblock (cdk_stream_t inp
, cdk_kbnode_t
* r_knode
)
1795 cdk_kbnode_t knode
, node
;
1796 cdk_desig_revoker_t revkeys
;
1798 u32 keyid
[2], main_keyid
[2];
1800 int key_seen
, got_key
;
1802 if (!inp
|| !r_knode
)
1805 return CDK_Inv_Value
;
1808 /* Reset all values. */
1809 keyid
[0] = keyid
[1] = 0;
1810 main_keyid
[0] = main_keyid
[1] = 0;
1813 key_seen
= got_key
= 0;
1817 while (!cdk_stream_eof (inp
))
1820 old_off
= cdk_stream_tell (inp
);
1821 rc
= cdk_pkt_read (inp
, pkt
);
1824 cdk_pkt_release (pkt
);
1828 { /* Release all packets we reached so far. */
1829 _cdk_log_debug ("keydb_get_keyblock: error %d\n", rc
);
1830 cdk_kbnode_release (knode
);
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
)
1841 if (key_seen
&& (pkt
->pkttype
== CDK_PKT_PUBLIC_KEY
||
1842 pkt
->pkttype
== CDK_PKT_SECRET_KEY
))
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
);
1850 if (pkt
->pkttype
== CDK_PKT_PUBLIC_KEY
||
1851 pkt
->pkttype
== CDK_PKT_SECRET_KEY
)
1853 _cdk_pkt_get_keyid (pkt
, main_keyid
);
1856 else if (pkt
->pkttype
== CDK_PKT_PUBLIC_SUBKEY
||
1857 pkt
->pkttype
== CDK_PKT_SECRET_SUBKEY
)
1859 if (pkt
->pkttype
== CDK_PKT_PUBLIC_SUBKEY
)
1861 pkt
->pkt
.public_key
->main_keyid
[0] = main_keyid
[0];
1862 pkt
->pkt
.public_key
->main_keyid
[1] = main_keyid
[1];
1866 pkt
->pkt
.secret_key
->main_keyid
[0] = main_keyid
[0];
1867 pkt
->pkt
.secret_key
->main_keyid
[1] = main_keyid
[1];
1870 /* We save this for the signature */
1871 _cdk_pkt_get_keyid (pkt
, keyid
);
1874 else if (pkt
->pkttype
== CDK_PKT_USER_ID
)
1876 else if (pkt
->pkttype
== CDK_PKT_SIGNATURE
)
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
;
1887 cdk_subpkt_find (pkt
->pkt
.signature
->hashed
,
1888 CDK_SIGSUBPKT_KEY_FLAGS
);
1891 unsigned int key_usage
= key_usage_to_cdk_usage (s
->d
[0]);
1892 add_key_usage (knode
, pkt
->pkt
.signature
->key
, key_usage
);
1895 node
= cdk_kbnode_new (pkt
);
1899 _cdk_kbnode_add (knode
, node
);
1904 keydb_merge_selfsig (knode
, main_keyid
);
1905 rc
= keydb_parse_allsigs (knode
, NULL
, 0);
1908 node
= cdk_kbnode_find (knode
, CDK_PKT_PUBLIC_KEY
);
1910 node
->pkt
->pkt
.public_key
->revkeys
= revkeys
;
1914 cdk_kbnode_release (knode
);
1915 *r_knode
= got_key
? knode
: NULL
;
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
)
1926 /* Return the type of the given data. In case it cannot be classified,
1927 a substring search will be performed. */
1929 classify_data (const byte
* buf
, size_t len
)
1934 if (buf
[0] == '0' && (buf
[1] == 'x' || buf
[1] == 'X'))
1935 { /* Skip hex prefix. */
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
;
1944 for (i
= 0; i
< len
; i
++)
1946 if (!isxdigit (buf
[i
]))
1947 return CDK_DBSEARCH_SUBSTR
;
1950 return CDK_DBSEARCH_SUBSTR
;
1954 type
= CDK_DBSEARCH_SHORT_KEYID
;
1957 type
= CDK_DBSEARCH_KEYID
;
1960 type
= CDK_DBSEARCH_FPR
;
1963 type
= CDK_DBSEARCH_SUBSTR
;
1973 * @hd: the keydb handle
1974 * @out: the output stream
1975 * @remusr: the list of key pattern to export
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.
1982 cdk_keydb_export (cdk_keydb_hd_t hd
, cdk_stream_t out
, cdk_strlist_t remusr
)
1984 cdk_kbnode_t knode
, node
;
1988 cdk_keydb_search_t st
;
1990 for (r
= remusr
; r
; r
= r
->next
)
1992 rc
= cdk_keydb_search_start (&st
, hd
, CDK_DBSEARCH_AUTO
, r
->d
);
1998 rc
= cdk_keydb_search (st
, hd
, &knode
);
1999 cdk_keydb_search_release (st
);
2007 node
= cdk_kbnode_find (knode
, CDK_PKT_PUBLIC_KEY
);
2011 return CDK_Error_No_Key
;
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)
2021 for (node
= knode
; node
; node
= node
->next
)
2023 /* No specified format; skip them */
2024 if (node
->pkt
->pkttype
== CDK_PKT_RING_TRUST
)
2026 /* We never export local signed signatures */
2027 if (node
->pkt
->pkttype
== CDK_PKT_SIGNATURE
&&
2028 !node
->pkt
->pkt
.signature
->flags
.exportable
)
2030 /* Filter out invalid signatures */
2031 if (node
->pkt
->pkttype
== CDK_PKT_SIGNATURE
&&
2032 (!KEY_CAN_SIGN (node
->pkt
->pkt
.signature
->pubkey_algo
)))
2035 /* Adjust the ctb flag if needed. */
2036 node
->pkt
->old_ctb
= old_ctb
;
2037 rc
= cdk_pkt_write (out
, node
->pkt
);
2040 cdk_kbnode_release (knode
);
2045 cdk_kbnode_release (knode
);
2053 find_key_packet (cdk_kbnode_t knode
, int *r_is_sk
)
2057 pkt
= cdk_kbnode_find_packet (knode
, CDK_PKT_PUBLIC_KEY
);
2060 pkt
= cdk_kbnode_find_packet (knode
, CDK_PKT_SECRET_KEY
);
2062 *r_is_sk
= pkt
? 1 : 0;
2068 /* Return 1 if the is allowd in a key node. */
2070 is_key_node (cdk_kbnode_t node
)
2072 switch (node
->pkt
->pkttype
)
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
:
2092 cdk_keydb_import (cdk_keydb_hd_t hd
, cdk_kbnode_t knode
)
2094 cdk_kbnode_t node
, chk
;
2103 return CDK_Inv_Value
;
2106 pkt
= find_key_packet (knode
, NULL
);
2110 return CDK_Inv_Packet
;
2113 _cdk_pkt_get_keyid (pkt
, keyid
);
2115 cdk_keydb_get_bykeyid (hd
, keyid
, &chk
);
2117 { /* FIXME: search for new signatures */
2118 cdk_kbnode_release (chk
);
2122 /* We append data to the stream so we need to close
2123 the stream here to re-open it later. */
2126 cdk_stream_close (hd
->fp
);
2130 rc
= _cdk_stream_append (hd
->name
, &out
);
2137 for (node
= knode
; node
; node
= node
->next
)
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
)
2144 _cdk_log_debug ("key db import: skip local signature\n");
2148 if (!is_key_node (node
))
2150 _cdk_log_debug ("key db import: skip invalid node of type %d\n",
2151 node
->pkt
->pkttype
);
2155 rc
= cdk_pkt_write (out
, node
->pkt
);
2158 cdk_stream_close (out
);
2164 cdk_stream_close (out
);
2165 hd
->stats
.new_keys
++;
2172 _cdk_keydb_check_userid (cdk_keydb_hd_t hd
, u32
* keyid
, const char *id
)
2174 cdk_kbnode_t knode
= NULL
, unode
= NULL
;
2177 cdk_keydb_search_t st
;
2182 return CDK_Inv_Value
;
2185 rc
= cdk_keydb_search_start (&st
, hd
, CDK_DBSEARCH_KEYID
, keyid
);
2191 rc
= cdk_keydb_search (st
, hd
, &knode
);
2192 cdk_keydb_search_release (st
);
2200 rc
= cdk_keydb_search_start (&st
, hd
, CDK_DBSEARCH_EXACT
, (char *) id
);
2203 rc
= cdk_keydb_search (st
, hd
, &unode
);
2204 cdk_keydb_search_release (st
);
2208 cdk_kbnode_release (knode
);
2214 cdk_keydb_search_start (&st
, hd
, CDK_DBSEARCH_KEYID
, keyid
);
2215 if (unode
&& find_by_keyid (unode
, st
))
2217 cdk_keydb_search_release (st
);
2218 cdk_kbnode_release (unode
);
2220 cdk_keydb_search_start (&st
, hd
, CDK_DBSEARCH_EXACT
, (char *) id
);
2221 if (knode
&& find_by_pattern (knode
, st
))
2223 cdk_keydb_search_release (st
);
2224 cdk_kbnode_release (knode
);
2226 return check
== 2 ? 0 : CDK_Inv_Value
;
2231 * cdk_keydb_check_sk:
2232 * @hd: the key db handle
2233 * @keyid: the 64-bit keyid
2235 * Check if a secret key with the given key ID is available
2236 * in the key database.
2239 cdk_keydb_check_sk (cdk_keydb_hd_t hd
, u32
* keyid
)
2249 return CDK_Inv_Value
;
2254 return CDK_Inv_Mode
;
2257 rc
= _cdk_keydb_open (hd
, &db
);
2264 while (!cdk_pkt_read (db
, pkt
))
2266 if (pkt
->pkttype
!= CDK_PKT_SECRET_KEY
&&
2267 pkt
->pkttype
!= CDK_PKT_SECRET_SUBKEY
)
2272 cdk_sk_get_keyid (pkt
->pkt
.secret_key
, kid
);
2273 if (KEYID_CMP (kid
, keyid
))
2275 cdk_pkt_release (pkt
);
2280 cdk_pkt_release (pkt
);
2282 return CDK_Error_No_Key
;
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
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.
2299 cdk_listkey_start (cdk_listkey_t
* r_ctx
, cdk_keydb_hd_t db
,
2300 const char *patt
, cdk_strlist_t fpatt
)
2309 return CDK_Inv_Value
;
2311 if ((patt
&& fpatt
) || (!patt
&& !fpatt
))
2314 return CDK_Inv_Mode
;
2316 rc
= _cdk_keydb_open (db
, &inp
);
2322 ctx
= cdk_calloc (1, sizeof *ctx
);
2326 return CDK_Out_Of_Core
;
2332 ctx
->u
.patt
= cdk_strdup (patt
);
2336 return CDK_Out_Of_Core
;
2342 for (l
= fpatt
; l
; l
= l
->next
)
2343 cdk_strlist_add (&ctx
->u
.fpatt
, l
->d
);
2345 ctx
->type
= patt
? 1 : 0;
2353 * cdk_listkey_close:
2354 * @ctx: the list key context
2356 * Free the list key context.
2359 cdk_listkey_close (cdk_listkey_t ctx
)
2365 cdk_free (ctx
->u
.patt
);
2367 cdk_strlist_free (ctx
->u
.fpatt
);
2374 * @ctx: list key context
2375 * @r_key: the pointer to the new key node object
2377 * Retrieve the next key from the pattern of the key list context.
2380 cdk_listkey_next (cdk_listkey_t ctx
, cdk_kbnode_t
* ret_key
)
2382 if (!ctx
|| !ret_key
)
2385 return CDK_Inv_Value
;
2390 return CDK_Inv_Mode
;
2393 if (ctx
->type
&& ctx
->u
.patt
[0] == '*')
2394 return cdk_keydb_get_keyblock (ctx
->inp
, ret_key
);
2398 struct cdk_keydb_search_s ks
;
2403 rc
= cdk_keydb_get_keyblock (ctx
->inp
, &node
);
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
))
2417 cdk_kbnode_release (node
);
2424 ctx
->t
= ctx
->u
.fpatt
;
2425 else if (ctx
->t
->next
)
2426 ctx
->t
= ctx
->t
->next
;
2429 return cdk_keydb_get_bypattern (ctx
->db
, ctx
->t
->d
, ret_key
);
2432 return CDK_General_Error
;
2437 _cdk_keydb_is_secret (cdk_keydb_hd_t db
)