1 /* genkey.c - Key generation.
2 Copyright (C) 2000 Werner Koch (dd9jn)
3 Copyright (C) 2001, 2002, 2003 g10 Code GmbH
5 This file is part of GPGME.
7 GPGME is free software; you can redistribute it and/or modify it
8 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.
12 GPGME is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GPGME; if not, write to the Free Software Foundation,
19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
34 struct _gpgme_op_genkey_result result;
36 /* The key parameters passed to the crypto engine. */
37 GpgmeData key_parameter;
42 release_op_data (void *hook)
44 op_data_t opd = (op_data_t) hook;
47 free (opd->result.fpr);
48 if (opd->key_parameter)
49 gpgme_data_release (opd->key_parameter);
54 gpgme_op_genkey_result (GpgmeCtx ctx)
59 err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, (void **) &opd, -1, NULL);
68 genkey_status_handler (void *priv, GpgmeStatusCode code, char *args)
70 GpgmeCtx ctx = (GpgmeCtx) priv;
74 /* Pipe the status code through the progress status handler. */
75 err = _gpgme_progress_status_handler (ctx, code, args);
79 err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, (void **) &opd,
86 case GPGME_STATUS_KEY_CREATED:
89 if (*args == 'B' || *args == 'P')
90 opd->result.primary = 1;
91 if (*args == 'B' || *args == 'S')
96 free (opd->result.fpr);
97 opd->result.fpr = strdup (&args[2]);
99 return GPGME_Out_Of_Core;
104 case GPGME_STATUS_EOF:
105 /* FIXME: Should return some more useful error value. */
106 if (!opd->result.primary && !opd->result.sub)
107 return GPGME_General_Error;
118 get_key_parameter (const char *parms, GpgmeData *key_parameter)
124 /* Extract the key parameter from the XML structure. */
125 parms = strstr (parms, "<GnupgKeyParms ");
127 return GPGME_Invalid_Value;
129 content = strchr (parms, '>');
131 return GPGME_Invalid_Value;
134 attrib = strstr (parms, "format=\"internal\"");
135 if (!attrib || attrib >= content)
136 return GPGME_Invalid_Value;
138 endtag = strstr (content, "</GnupgKeyParms>");
139 /* FIXME: Check that there are no control statements inside. */
140 while (*content == '\n')
143 return gpgme_data_new_from_mem (key_parameter, content,
144 endtag - content, 0);
149 genkey_start (GpgmeCtx ctx, int synchronous, const char *parms,
150 GpgmeData pubkey, GpgmeData seckey)
154 err = _gpgme_op_reset (ctx, synchronous);
158 err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, (void **) &opd,
159 sizeof (*opd), release_op_data);
163 err = get_key_parameter (parms, &opd->key_parameter);
167 _gpgme_engine_set_status_handler (ctx->engine, genkey_status_handler, ctx);
169 return _gpgme_engine_op_genkey (ctx->engine, opd->key_parameter,
170 ctx->use_armor, pubkey, seckey);
174 /* Generate a new keypair and add it to the keyring. PUBKEY and
175 SECKEY should be null for now. PARMS specifies what keys should be
178 gpgme_op_genkey_start (GpgmeCtx ctx, const char *parms,
179 GpgmeData pubkey, GpgmeData seckey)
181 return genkey_start (ctx, 0, parms, pubkey, seckey);
185 /* Generate a new keypair and add it to the keyring. PUBKEY and
186 SECKEY should be null for now. PARMS specifies what keys should be
189 gpgme_op_genkey (GpgmeCtx ctx, const char *parms, GpgmeData pubkey,
194 err = genkey_start (ctx, 1, parms, pubkey, seckey);
196 err = _gpgme_wait_one (ctx);