root/openpgpsdk/trunk/src/lib/std_keyring.c

Revision 568 (checked in by rachel, 5 years ago)

Implemented high-level function ops_sign_mem and corresponding test.

Line 
1 /*! \file
2   \brief Standard API keyring functions
3
4 */
5
6 /** @defgroup StdKeyring Keyring
7     \ingroup StandardAPI
8
9     @defgroup StdKeyringFile Keyring File Operations
10     \ingroup StdKeyring
11     \brief Keyring Open/Read/Write/Close
12
13     Example Usage:
14     \code
15
16     // definition of variables
17     ops_keyring_t keyring;
18     char* filename="~/.gnupg/pubring.gpg";
19
20     // Read keyring from file
21     ops_keyring_read_from_file(&keyring,filename);
22
23     // do actions using keyring   
24     ...
25
26     // Free memory alloc-ed in ops_keyring_read_from_file()
27     ops_keyring_free();
28     \endcode
29 */
30
31 /**
32     @defgroup StdKeyringFind Keyfind Find Operations
33     \ingroup StdKeyring
34     Find Key or its info within keyring
35
36     Example Usage:
37     \code
38
39     // definition of variables
40     ops_keyring_t keyring;
41     unsigned char* keyid;
42     ops_key_data_t *key;
43
44     // Read keyring from file
45     ops_keyring_read_from_file(&keyring,"~/.gnupg/pubring.gpg");
46
47     // Search for keys
48
49     // - get Key ID from given userid
50     keyid=ops_keyring_find_keyid_by_userid (keyring, "user@domain.com")
51
52     // - now get key from Key ID
53     key=ops_keyring_find_key_by_id(keyring, keyid);
54
55     // do something with key
56     ...
57     
58     // Free memory alloc-ed in ops_keyring_read_from_file()
59     ops_keyring_free();
60     \endcode
61  */
62
63 #include <assert.h>
64 #include <fcntl.h>
65 #include <stdlib.h>
66 #include <string.h>
67 #ifndef WIN32
68  #include <unistd.h>
69 #endif
70
71 #include "openpgpsdk/packet.h"
72 #include "keyring_local.h"
73
74 #include "openpgpsdk/accumulate.h"
75 #include "openpgpsdk/armour.h"
76 #include "openpgpsdk/keyring.h"
77 #include "openpgpsdk/util.h"
78 #include "openpgpsdk/std_print.h"
79 #include "openpgpsdk/readerwriter.h"
80
81 static ops_parse_cb_return_t
82 cb_keyring_read(const ops_parser_content_t *content_,
83                 ops_parse_cb_info_t *cbinfo);
84
85 /**
86    \ingroup StdKeyringFile
87   
88    Reads a keyring from a file
89   
90    \param keyring Ptr to existing keyring
91    \param file Filename of keyring
92   
93    \note Keyring struct must already exist.
94
95    \note Can be used with either a public or secret keyring.
96
97    \note You must call ops_keyring_free() after usage to free alloc-ed memory.
98
99    \note If you call this twice on the same keyring struct, without calling
100    ops_keyring_free() between these calls, you will introduce a memory leak.
101 */
102 ops_boolean_t ops_keyring_read_from_file(ops_keyring_t *keyring, const ops_boolean_t armour, const char *filename)
103     {
104     ops_parse_info_t *pinfo;
105     int fd;
106     ops_boolean_t res = ops_true;
107
108     //memset(keyring,'\0',sizeof *keyring);
109
110     pinfo=ops_parse_info_new();
111
112     // add this for the moment,
113     // \todo need to fix the problems with reading signature subpackets later
114
115     //    ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_RAW);
116     ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED);
117
118 #ifdef WIN32
119     fd=open(filename,O_RDONLY|O_BINARY);
120 #else
121     fd=open(filename,O_RDONLY);
122 #endif
123     if(fd < 0)
124         {
125         ops_parse_info_delete(pinfo);
126         perror(filename);
127         return ops_false;
128         }
129
130     ops_reader_set_fd(pinfo,fd);
131
132     ops_parse_cb_set(pinfo,cb_keyring_read,NULL);
133
134     if (armour)
135         { ops_reader_push_dearmour(pinfo, ops_false, ops_false, ops_false); }
136
137     if ( ops_parse_and_accumulate(keyring,pinfo) == 0 ) {
138         res = ops_false;
139     }
140     else
141         {
142         res = ops_true;
143         }
144     ops_print_errors(ops_parse_info_get_errors(pinfo));
145
146     close(fd);
147
148     ops_parse_info_delete(pinfo);
149
150     return res;
151     }
152
153 /**
154    \ingroup StdKeyring
155   
156    Reads a keyring from memory
157   
158    \param keyring Ptr to existing keyring
159    \param mem ptr to memory struct containing keyring info
160   
161    \note Keyring struct must already exist.
162
163    \note Can be used with either a public or secret keyring.
164
165    \note You must call ops_keyring_free() after usage to free alloc-ed memory.
166
167    \note If you call this twice on the same keyring struct, without calling
168    ops_keyring_free() between these calls, you will introduce a memory leak.
169 */
170 ops_boolean_t ops_keyring_read_from_mem(ops_keyring_t *keyring, ops_memory_t* mem)
171     {
172     // \todo currently assuming this is an armoured key.
173
174     ops_parse_info_t *pinfo=NULL;
175     ops_boolean_t res = ops_true;
176
177     // \todo need to free memory first?
178     //memset(keyring,'\0',sizeof *keyring);
179
180     pinfo=ops_parse_info_new();
181     ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED);
182
183     ops_setup_memory_read(&pinfo, mem, NULL, cb_keyring_read);
184
185     ops_reader_push_dearmour(pinfo,ops_false,ops_false,ops_true);
186
187     if ( ops_parse_and_accumulate(keyring,pinfo) == 0 )
188         {
189         res = ops_false;
190         }
191     else
192         {
193         res = ops_true;
194         }
195     ops_print_errors(ops_parse_info_get_errors(pinfo));
196
197     ops_reader_pop_dearmour(pinfo);
198
199     // don't call teardown_memory_read because memory was passed in
200     ops_parse_info_delete(pinfo);
201
202     return res;
203     }
204
205 /**
206    \ingroup StdKeyringFile
207  
208    Frees alloc-ed memory
209  
210    \param keyring Keyring whose data is to be freed
211   
212    \note This does not free keyring itself, just the memory alloc-ed in it.
213  */
214 void ops_keyring_free(ops_keyring_t *keyring)
215     {
216     free(keyring->keys);
217     keyring->keys=NULL;
218     keyring->nkeys=0;
219     keyring->nkeys_allocated=0;
220     }
221
222 /**
223    \ingroup StdKeyringFind
224
225    Finds key in keyring from its Key ID
226
227    \param keyring Keyring to be searched
228    \param keyid ID of required key
229
230    \return Ptr to key, if found; NULL, if not found
231 */
232 const ops_keydata_t *
233 ops_keyring_find_key_by_id(const ops_keyring_t *keyring,
234                            const unsigned char keyid[OPS_KEY_ID_SIZE])
235     {
236     int n;
237
238     if (!keyring)
239         return NULL;
240
241     for(n=0 ; n < keyring->nkeys ; ++n)
242         {
243         if(!memcmp(keyring->keys[n].key_id,keyid,OPS_KEY_ID_SIZE))
244             return &keyring->keys[n];
245         }
246
247     return NULL;
248     }
249
250 /**
251    \ingroup StdKeyringFind
252
253    Finds key from its User ID
254
255    \param keyring Keyring to be searched
256    \param userid User ID of required key
257
258    \return Ptr to Key, if found; NULL, if not found
259 */
260 const ops_keydata_t *
261 ops_keyring_find_key_by_userid(const ops_keyring_t *keyring,
262                                  const char *userid)
263     {
264     int n=0;
265     unsigned int i=0;
266
267     if (!keyring)
268         return NULL;
269
270     for(n=0 ; n < keyring->nkeys ; ++n)
271         {
272         for(i=0; i<keyring->keys[n].nuids; i++)
273             {
274             //printf("[%d][%d] userid %s\n",n,i,keyring->keys[n].uids[i].user_id);
275             if(!strncmp((char *)keyring->keys[n].uids[i].user_id,userid,strlen(userid)))
276                 return &keyring->keys[n];
277             }
278         }
279
280     //printf("end: n=%d,i=%d\n",n,i);
281     return NULL;
282     }
283
284 /**
285    \ingroup StdKeyringList
286
287    List keys in keyring
288
289    \param keyring Keyring to use
290    \param match optional string to match
291
292 */
293
294 void
295 ops_keyring_list(const ops_keyring_t* keyring,
296                  const char* match)
297     {
298     int n;
299     unsigned int i;
300     ops_keydata_t* key;
301
302     printf ("%d keys\n", keyring->nkeys);
303     for(n=0,key=&keyring->keys[n] ; n < keyring->nkeys ; ++n,++key)
304         {
305         for(i=0; i<key->nuids; i++)
306             {
307             if (match)
308                 printf ("*** match %s\n", match);
309             // if match, compare
310             //      if(!strcmp((char *)keyring->keys[n].uids[i].user_id,userid))
311             //         return &keyring->keys[n].keyid[0];
312             if (ops_key_is_secret(key))
313                 ops_print_secret_keydata(key);
314             else
315                 ops_print_public_keydata(key);
316             }
317
318         }
319     }
320
321 /* Static functions */
322
323 static ops_parse_cb_return_t
324 cb_keyring_read(const ops_parser_content_t *content_,
325                 ops_parse_cb_info_t *cbinfo)
326     {
327     OPS_USED(cbinfo);
328
329     switch(content_->tag)
330         {
331     case OPS_PARSER_PTAG:
332     case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: // we get these because we didn't prompt
333     case OPS_PTAG_CT_SIGNATURE_HEADER:
334     case OPS_PTAG_CT_SIGNATURE_FOOTER:
335     case OPS_PTAG_CT_SIGNATURE:
336     case OPS_PTAG_CT_TRUST:
337     case OPS_PARSER_ERRCODE:
338         break;
339
340     default:
341         ;
342         }
343
344     return OPS_RELEASE_MEMORY;
345     }
346
347 /*\@}*/
348
349 /* end of file */
Note: See TracBrowser for help on using the browser.