Update head to match stable 1.0
[gnupg.git] / g10 / kbxfile.c
1 /* kbxfile.c - KBX file handling
2  *      Copyright (C) 2000 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 /****************
22  * We will change the whole system to use only KBX.  This file here
23  * will implement the methods needed to operate on plain KBXfiles.
24  * Most stuff from getkey and ringedit will be replaced by stuff here.
25  * To make things even more easier we will only allow one updateable kbxfile
26  * and optionally some read-only files.
27  */
28
29 #include <config.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <assert.h>
35 #include <gcrypt.h>
36
37 #include "kbx.h"
38 #include "options.h"
39 #include "util.h"
40 #include "i18n.h"
41 #include "main.h"
42
43 /****************
44  * Read the blob at the current fileposition and return an allocated
45  * pointer nto the blob if it was found.
46  * Fixme: return a blob object.
47  */
48 static int
49 do_search_by_fpr ( const char *filename, FILE *a, const char *fpr,
50                                                   KBXBLOB *r_blob )
51 {
52     KBXBLOB blob;
53     int rc;
54
55     *r_blob = NULL;
56     rc = kbx_read_blob ( &blob, a );
57     if ( rc && rc != -1 ) {
58         log_error (_("file `%s': error reading blob\n"), filename );
59     }
60     else if ( !rc ) {
61         rc = kbx_blob_has_fpr ( blob, fpr );
62     }
63     else
64         log_info ("eof\n");
65
66     if ( !rc ) {
67         *r_blob = blob;
68     }
69     else {
70         kbx_release_blob ( blob );
71     }
72     return rc;
73 }
74
75 int
76 kbxfile_search_by_fpr( const char *filename, const byte *fpr )
77 {
78     FILE *fp;
79     KBXBLOB blob;
80     int rc;
81
82     fp = fopen ( filename, "rb" );
83     if( !fp ) {
84         log_error(_("can't open `%s': %s\n"), filename, strerror(errno) );
85         return 1;
86     }
87
88     while ( (rc=do_search_by_fpr ( filename, fp, fpr, &blob )) == -1 )
89         ;
90     if ( !rc ) {
91         fputs ("FOUND\n", stderr );
92         kbx_dump_blob ( stderr, blob );
93         kbx_release_blob ( blob );
94     }
95
96     fclose (fp);
97     return -1;
98 }
99
100
101 /****************
102  * Read the blob at the current fileposition and return an allocated
103  * pointer nto the blob if it was found.
104  * Fixme: return a blob object.
105  */
106 static int
107 do_search_by_keyid ( const char *filename, FILE *a,
108                      const byte *keyidbuf, size_t keyidlen, KBXBLOB *r_blob )
109 {
110     KBXBLOB blob;
111     int rc;
112
113     *r_blob = NULL;
114     rc = kbx_read_blob ( &blob, a );
115     if ( rc && rc != -1 ) {
116         log_error (_("file `%s': error reading blob\n"), filename );
117     }
118     else if ( !rc ) {
119         rc = kbx_blob_has_kid ( blob, keyidbuf, keyidlen );
120     }
121     else
122         rc = GPGERR_GENERAL;  /* eof */
123
124     if ( !rc ) {
125         *r_blob = blob;
126     }
127     else {
128         kbx_release_blob ( blob );
129     }
130     return rc;
131 }
132
133 /****************
134  * Look for a KBX described by an keyid.  This function will in
135  * turn return each matching keyid because there may me duplicates
136  * (which can't happen for fingerprints)
137  * mode 10 = short keyid
138  *      11 = long keyid
139  */
140 int
141 kbxfile_search_by_kid ( const char *filename, u32 *kid, int mode )
142 {
143     FILE *fp;
144     KBXBLOB blob;
145     int rc;
146     byte kbuf[8], *kbufptr;
147     int kbuflen;
148
149     fp = fopen ( filename, "rb" );
150     if( !fp ) {
151         log_error(_("can't open `%s': %s\n"), filename, strerror(errno) );
152         return 1;
153     }
154
155     kbuf[0] = kid[0] >> 24;
156     kbuf[1] = kid[0] >> 16;
157     kbuf[2] = kid[0] >> 8;
158     kbuf[3] = kid[0];
159     kbuf[4] = kid[1] >> 24;
160     kbuf[5] = kid[1] >> 16;
161     kbuf[6] = kid[1] >> 8;
162     kbuf[7] = kid[1];
163     if ( mode == 10 ) {
164         kbufptr=kbuf+4;
165         kbuflen = 4;
166     }
167     else if (mode == 11 ) {
168         kbufptr=kbuf;
169         kbuflen = 8;
170     }
171     else {
172         BUG();
173     }
174
175     do {
176         while ( (rc=do_search_by_keyid ( filename, fp,
177                                          kbufptr, kbuflen, &blob )) == -1 )
178             ;
179         if ( !rc ) {
180             fputs ("FOUND:\n", stderr );
181             kbx_dump_blob ( stderr, blob );
182             kbx_release_blob ( blob );
183         }
184     } while ( !rc );
185
186     fclose (fp);
187     return -1;
188 }
189
190
191 static int
192 do_search_by_uid ( const char *filename, FILE *a,
193                     int (*cmpfnc)(const byte*,size_t,void*), void *cmpdata,
194                                                            KBXBLOB *r_blob )
195 {
196     KBXBLOB blob;
197     int rc;
198
199     *r_blob = NULL;
200     rc = kbx_read_blob ( &blob, a );
201     if ( rc && rc != -1 ) {
202         log_error (_("file `%s': error reading blob\n"), filename );
203     }
204     else if ( !rc ) {
205         rc = kbx_blob_has_uid ( blob, cmpfnc, cmpdata );
206     }
207     else
208         rc = GPGERR_GENERAL;  /* eof */
209
210     if ( !rc ) {
211         *r_blob = blob;
212     }
213     else {
214         kbx_release_blob ( blob );
215     }
216     return rc;
217 }
218
219
220 static int
221 substr_compare ( const byte *buf, size_t buflen, void *opaque )
222 {
223     return !!memistr ( buf, buflen, opaque );
224 }
225
226
227 int
228 kbxfile_search_by_uid ( const char *filename, const char *name )
229 {
230     FILE *fp;
231     KBXBLOB blob;
232     int rc;
233     byte kbuf[8], *kbufptr;
234     int kbuflen;
235
236     fp = fopen ( filename, "rb" );
237     if( !fp ) {
238         log_error(_("can't open `%s': %s\n"), filename, strerror(errno) );
239         return 1;
240     }
241
242
243     do {
244         while ( (rc=do_search_by_uid ( filename, fp,
245                                         substr_compare, name, &blob )) == -1 )
246             ;
247         if ( !rc ) {
248             fputs ("FOUND:\n", stderr );
249             kbx_dump_blob ( stderr, blob );
250             kbx_release_blob ( blob );
251         }
252     } while ( !rc );
253
254     fclose ( fp );
255     return -1;
256 }
257
258
259
260 void
261 export_as_kbxfile(void)
262 {
263
264     KBPOS kbpos;
265     KBNODE keyblock = NULL;
266     int rc=0;
267
268     rc = enum_keyblocks_begin( &kbpos, 0 );
269     if( rc ) {
270         if( rc != -1 )
271             log_error("enum_keyblocks(open) failed: %s\n", gpg_errstr(rc) );
272         goto leave;
273     }
274
275     while( !(rc = enum_keyblocks_next( kbpos, 1, &keyblock )) ) {
276         KBXBLOB blob;
277         const char *p;
278         size_t n;
279
280         merge_keys_and_selfsig( keyblock );
281         rc = kbx_create_blob ( &blob, keyblock );
282         if( rc ) {
283             log_error("kbx_create_blob failed: %s\n", gpg_errstr(rc) );
284             goto leave;
285         }
286         p = kbx_get_blob_image ( blob, &n );
287         fwrite( p, n, 1, stdout );
288         kbx_release_blob ( blob );
289     }
290
291     if( rc && rc != -1 )
292         log_error("enum_keyblocks(read) failed: %s\n", gpg_errstr(rc));
293
294   leave:
295     enum_keyblocks_end( kbpos );
296     release_kbnode( keyblock );
297 }
298
299
300 static int
301 do_print_kbxfile( const char *filename, FILE *a )
302 {
303     KBXBLOB blob;
304     int rc;
305
306     rc = kbx_read_blob ( &blob, a );
307     if ( rc && rc != -1 ) {
308         log_error (_("file `%s': error reading blob\n"), filename );
309     }
310     else if ( ! rc )
311         kbx_dump_blob ( stdout, blob );
312     kbx_release_blob ( blob );
313     return rc;
314 }
315
316 void
317 print_kbxfile( const char *filename )
318 {
319     FILE *fp;
320
321     fp = fopen ( filename, "rb" );
322     if( !fp ) {
323         log_error(_("can't open `%s': %s\n"), filename, strerror(errno) );
324         return;
325     }
326
327     while ( !do_print_kbxfile( filename, fp ) )
328         ;
329
330     fclose (fp);
331 }
332