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

Contents of /trunk/MyGPGME/genkey.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Fri Sep 30 10:10:16 2005 UTC (19 years, 5 months ago) by twoaday
File MIME type: text/plain
File size: 12069 byte(s)
Almost finished phase 1 of the WinPT GPGME port.
Still need more cleanup, comments and tests.


1 /* 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 if( (p = strchr (args, ' ')) != NULL ) {
40 *p++ = 0;
41 if (*p) {
42 type = *(byte*)p;
43 if( (p = strchr (p+1, ' ')) != NULL ) {
44 *p++ = 0;
45 if( *p ) {
46 current = atoi (p);
47 if( (p = strchr (p+1, ' ')) != NULL ) {
48 *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 if( (parms = strstr (parms, "<GnupgKeyParms " )) != NULL
145 && (s = strchr (parms, '>')) != NULL
146 && (sx = strstr( parms, "format=\"internal\"" )) != NULL
147 && sx < s
148 && (s2 = strstr( s+1, "</GnupgKeyParms>" )) != NULL) {
149 /* 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 if (prog_cb)
394 gpgme_set_progress_cb (ctx, prog_cb, NULL);
395 err = gpgme_op_genkey (ctx, params, NULL, NULL);
396 if (fpr)
397 *fpr = ctx->keygen_fpr? strdup (ctx->keygen_fpr) : NULL;
398 gpgme_release (ctx);
399 return err;
400 } /* gpgme_op_genkey_auto */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26