/[winpt]/trunk/MyGPGME/genkey.c
ViewVC logotype

Annotation of /trunk/MyGPGME/genkey.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Mon Apr 4 07:01:43 2005 UTC (19 years, 10 months ago) by twoaday
File MIME type: text/plain
File size: 12077 byte(s)
2005-03-22  Timo Schulz  <twoaday@freakmail.de>
                                                                                
        * editcard.c: Support new status-fd entries SC_OP_SUCCESS
        and SC_OP_FAILURE.
        * editkey.c (cmd_addrev_handler): Check if context != NULL.
        * import.c (import_command_handler): Wrong function signature.
        Noted by Kurt Fitzner.
        * types.h: Fixed encrypt_result_s. Noted by Kurt.
        * gpgme.h (gpgme_editkey_addrev_set): Changed return type.
        Kudos to Kurt.
        * key.c: Removed some unreachable code. By Kurt.
                                                                                


1 twoaday 2 /* genkey.c - key generation
2     * Copyright (C) 2000, 2001 Werner Koch (dd9jn), g10 Code GmbH
3     * Copyright (C) 2001-2004 Timo Schulz
4     *
5     * This file is part of MyGPGME.
6     *
7     * MyGPGME is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * MyGPGME is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20     */
21    
22     #include <stdio.h>
23     #include <stdlib.h>
24     #include <string.h>
25    
26     #include "util.h"
27     #include "context.h"
28     #include "ops.h"
29    
30    
31     void
32     _gpgme_genkey_status_handler( gpgme_ctx_t ctx, gpg_status_code_t code, char *args )
33     {
34     if( code == STATUS_PROGRESS && *args ) {
35     if( ctx->cb.progress ) {
36     char *p;
37     int type=0, current=0, total=0;
38    
39 twoaday 7 if( (p = strchr (args, ' ')) != NULL ) {
40 twoaday 2 *p++ = 0;
41     if (*p) {
42     type = *(byte*)p;
43 twoaday 7 if( (p = strchr (p+1, ' ')) != NULL ) {
44 twoaday 2 *p++ = 0;
45     if( *p ) {
46     current = atoi (p);
47 twoaday 7 if( (p = strchr (p+1, ' ')) != NULL ) {
48 twoaday 2 *p++ = 0;
49     total = atoi (p);
50     }
51     }
52     }
53     }
54     }
55     if( type != 'X' )
56     ctx->cb.progress( ctx->cb.progress_value, args, type,
57     current, total );
58     }
59     return;
60     }
61     if (code == STATUS_KEY_CREATED) {
62     char * p;
63     safe_free (ctx->keygen_fpr);
64     p = ctx->keygen_fpr = strdup (args+2);
65     if (!p)
66     ctx->out_of_core = 1;
67     }
68     DEBUG2 ("genkey_status: code=%d args=`%s'\n", code, args );
69     }
70    
71    
72     /*
73     * Here is how the parms should be formatted:
74     <GnupgKeyParms format="internal">
75     Key-Type: DSA
76     Key-Length: 1024
77     Subkey-Type: ELG-E
78     Subkey-Length: 1024
79     Name-Real: Joe Tester
80     Name-Comment: with stupid passphrase
81     Name-Email: [email protected]
82     Expire-Date: 0
83     Passphrase: abc
84     </GnupgKeyParms>
85     * Strings should be given in UTF-8 encoding. The format we support for now
86     * "internal". The content of the <GnupgKeyParms> container is passed
87     * verbatim to GnuPG. Control statements (e.g. %pubring) are not allowed.
88     */
89     gpgme_error_t
90     gpgme_op_genkey_start( gpgme_ctx_t c, const char * parms,
91     gpgme_data_t pubkey, gpgme_data_t seckey )
92     {
93     gpgme_error_t rc = 0;
94     const char * s, * s2, * sx;
95    
96     fail_on_pending_request( c );
97     c->pending = 1;
98    
99     gpgme_data_release( c->help_data_1 );
100     c->help_data_1 = NULL;
101    
102     /* create a process object */
103     _gpgme_gpg_release( &c->gpg );
104     rc = _gpgme_gpg_new( &c->gpg );
105     if( rc )
106     goto leave;
107    
108     /* We need a special mechanism to get the fd of a pipe here, so
109     * that we can use this for the %pubring and %secring parameters.
110     * We don't have this yet, so we implement only the adding to the
111     * standard keyrings */
112     if( pubkey || seckey ) {
113     rc = mk_error( Not_Implemented );
114     goto leave;
115     }
116    
117     if( c->use_logging )
118     _gpgme_gpg_set_logging_handler( c->gpg, c );
119     _gpgme_gpg_set_status_handler( c->gpg, _gpgme_genkey_status_handler, c );
120    
121     /* build the commandline */
122     _gpgme_gpg_add_arg ( c->gpg, "--gen-key" );
123     if( c->use_armor )
124     _gpgme_gpg_add_arg ( c->gpg, "--armor" );
125     if ( !pubkey && !seckey )
126     ; /* okay: Add key to the keyrings */
127     else if( !pubkey
128     || gpgme_data_get_type( pubkey ) != GPGME_DATA_TYPE_NONE ) {
129     rc = mk_error ( Invalid_Value );
130     goto leave;
131     }
132     else if( !seckey
133     || gpgme_data_get_type( seckey ) != GPGME_DATA_TYPE_NONE ) {
134     rc = mk_error ( Invalid_Value );
135     goto leave;
136     }
137    
138     if( pubkey ) {
139     _gpgme_data_set_mode( pubkey, GPGME_DATA_MODE_IN );
140     _gpgme_data_set_mode( seckey, GPGME_DATA_MODE_IN );
141     /* need some more things here */
142     }
143    
144 twoaday 7 if( (parms = strstr (parms, "<GnupgKeyParms " )) != NULL
145     && (s = strchr (parms, '>')) != NULL
146 twoaday 2 && (sx = strstr( parms, "format=\"internal\"" ))
147     && sx < s
148 twoaday 7 && (s2 = strstr( s+1, "</GnupgKeyParms>" )) != NULL) {
149 twoaday 2 /* fixme: check that there are no control statements inside */
150     rc = gpgme_data_new_from_mem( &c->help_data_1, s + 1, s2 - s - 1, 1 );
151     }
152     else
153     rc = mk_error( Invalid_Value );
154     if( rc )
155     goto leave;
156    
157     _gpgme_data_set_mode( c->help_data_1, GPGME_DATA_MODE_OUT );
158     _gpgme_gpg_add_data( c->gpg, c->help_data_1, 0 );
159     rc = _gpgme_gpg_spawn ( c->gpg, c );
160    
161     leave:
162     if( rc ) {
163     c->pending = 0;
164     _gpgme_gpg_release ( &c->gpg );
165     }
166    
167     return rc;
168     }
169    
170    
171     /**
172     * gpgme_op_genkey:
173     * @c: the context
174     * @parms: XML string with the key parameters
175     * @pubkey: Returns the public key
176     * @seckey: Returns the secret key
177     *
178     * Generate a new key and store the key in the default keyrings if both
179     * @pubkey and @seckey are NULL. If @pubkey and @seckey are given, the newly
180     * created key will be returned in these data objects.
181     * See gpgme_op_genkey_start() for a description of @parms.
182     *
183     * Return value: 0 for success or an error code
184     **/
185     gpgme_error_t
186     gpgme_op_genkey( gpgme_ctx_t c, const char * parms,
187     gpgme_data_t pubkey, gpgme_data_t seckey )
188    
189     {
190     gpgme_error_t rc;
191    
192     rc = gpgme_op_genkey_start ( c, parms, pubkey, seckey );
193     if( !rc ) {
194     gpgme_wait ( c, 1 );
195     c->pending = 0;
196     }
197    
198     return rc;
199     } /* gpgme_op_genkey */
200    
201     static const char key_params[] =
202     "<GnupgKeyParms format=\"internal\">\n"
203     "Key-Type: %s\n"
204     "Key-Length: %d\n"
205     "Subkey-Type: %s\n"
206     "Subkey-Length: %d\n"
207     "Name-Real: %s\n"
208     "Name-Email: %s\n"
209     "Expire-Date: %s\n"
210     "Passphrase: %s\n"
211     "</GnupgKeyParms>\n";
212    
213     static const char key_params_with_comment[] =
214     "<GnupgKeyParms format=\"internal\">\n"
215     "Key-Type: %s\n"
216     "Key-Length: %d\n"
217     "Subkey-Type: %s\n"
218     "Subkey-Length: %d\n"
219     "Name-Real: %s\n"
220     "Name-Comment: %s\n"
221     "Name-Email: %s\n"
222     "Expire-Date: %s\n"
223     "Passphrase: %s\n"
224     "</GnupgKeyParms>\n";
225    
226     static const char key_params_one[] =
227     "<GnupgKeyParms format=\"internal\">\n"
228     "Key-Type: %s\n"
229     "Key-Length: %d\n"
230     "Key-Usage: %s\n"
231     "Name-Real: %s\n"
232     "Name-Email: %s\n"
233     "Expire-Date: %s\n"
234     "Passphrase: %s\n"
235     "</GnupgKeyParms>\n";
236    
237     static const char key_params_one_with_comment[] =
238     "<GnupgKeyParms format=\"internal\">\n"
239     "Key-Type: %s\n"
240     "Key-Length: %d\n"
241     "Key-Usage: %s\n"
242     "Name-Real: %s\n"
243     "Name-Email: %s\n"
244     "Name-Comment: %s\n"
245     "Expire-Date: %s\n"
246     "Passphrase: %s\n"
247     "</GnupgKeyParms>\n";
248    
249    
250     char *
251     gpgme_genkey_params( int keytype, int bits,
252     const char * user, const char * comment,const char * email,
253     const char * expdate, const char * passphrase )
254     {
255     char *p = NULL;
256     int addsize = strlen("sign encrypt");
257     int size = 0;
258    
259     if( keytype == GPGME_KEYGEN_NONE )
260     return NULL;
261    
262     if( comment && *comment ) {
263     size = strlen( key_params_with_comment )
264     + 16
265     + strlen( user )
266     + addsize
267     + strlen( comment )
268     + strlen( email )
269     + strlen( passphrase ) + 32;
270     }
271     else {
272     size = strlen( key_params )
273     + 16
274     + strlen( user )
275     + strlen( email )
276     + strlen( passphrase )
277     + addsize
278     + 32;
279     }
280     if( expdate )
281     size += strlen( expdate );
282     p = malloc( size+1 );
283     if( !p )
284     return NULL;
285     if( comment && *comment ) {
286     switch( keytype ) {
287     case GPGME_KEYGEN_DSA_ELG:
288     sprintf( p, key_params_with_comment,
289     "DSA", 1024, "ELG-E", bits, user, comment, email,
290     expdate ? expdate : "0", passphrase );
291     break;
292    
293     case GPGME_KEYGEN_DSA_RSA:
294     sprintf( p, key_params_with_comment,
295     "DSA", 1024, "RSA", bits, user, comment, email,
296     expdate ? expdate : "0", passphrase );
297     break;
298    
299     case GPGME_KEYGEN_DSA_SIG:
300     sprintf( p, key_params_one_with_comment,
301     "DSA", 1024, "sign",
302     user, comment, email,
303     expdate ? expdate : "0", passphrase );
304     break;
305    
306     case GPGME_KEYGEN_RSA_SIG:
307     sprintf( p, key_params_one_with_comment,
308     "RSA", bits, "sign",
309     user, comment, email,
310     expdate ? expdate : "0", passphrase );
311     break;
312    
313     case GPGME_KEYGEN_RSA:
314     sprintf( p, key_params_one_with_comment,
315     "RSA", bits, "sign encrypt",
316     user, comment, email,
317     expdate ? expdate : "0", passphrase );
318     break;
319    
320     case GPGME_KEYGEN_RSA_RSA:
321     sprintf( p, key_params_with_comment,
322     "RSA", bits, "RSA", bits, user, comment, email,
323     expdate? expdate : "0", passphrase );
324     break;
325    
326     default:
327     safe_free( p );
328     p = NULL;
329     break;
330     }
331     }
332     else {
333     switch ( keytype ) {
334     case GPGME_KEYGEN_DSA_ELG:
335     sprintf( p, key_params,
336     "DSA", 1024, "ELG-E", bits, user, email,
337     expdate ? expdate : "0", passphrase );
338     break;
339    
340     case GPGME_KEYGEN_DSA_RSA:
341     sprintf( p, key_params,
342     "DSA", 1024, "RSA", bits, user, email,
343     expdate ? expdate : "0", passphrase );
344     break;
345    
346     case GPGME_KEYGEN_DSA_SIG:
347     sprintf( p, key_params_one,
348     "DSA", 1024, "sign",
349     user, email,
350     expdate ? expdate : "0", passphrase );
351     break;
352    
353     case GPGME_KEYGEN_RSA_SIG:
354     sprintf( p, key_params_one,
355     "RSA", bits, "sign",
356     user, email,
357     expdate ? expdate : "0", passphrase );
358     break;
359    
360     case GPGME_KEYGEN_RSA:
361     sprintf( p, key_params_one,
362     "RSA", bits, "sign encrypt",
363     user, email,
364     expdate ? expdate : "0", passphrase );
365     break;
366    
367     case GPGME_KEYGEN_RSA_RSA:
368     sprintf( p, key_params,
369     "RSA", bits, "RSA", bits, user, email,
370     expdate? expdate : "0", passphrase );
371     break;
372    
373     default:
374     safe_free( p );
375     p = NULL;
376     break;
377     }
378     }
379     return p;
380     } /* gpgme_genkey_params */
381    
382    
383     gpgme_error_t
384     gpgme_op_genkey_auto( const char * params, gpgme_progress_cb_t prog_cb,
385     char ** fpr )
386     {
387     gpgme_error_t err = 0;
388     gpgme_ctx_t ctx;
389    
390     err = gpgme_new( &ctx );
391     if( err )
392     return err;
393    
394     if( prog_cb )
395     gpgme_set_progress_cb( ctx, prog_cb, NULL );
396     err = gpgme_op_genkey( ctx, params, NULL, NULL );
397     if( fpr )
398     *fpr = ctx->keygen_fpr? strdup( ctx->keygen_fpr ) : NULL;
399     gpgme_release( ctx );
400     return err;
401     } /* gpgme_op_genkey_auto */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26