aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2000-12-18 20:54:43 +0000
committerWerner Koch <[email protected]>2000-12-18 20:54:43 +0000
commita92ecd447027258e2674719bc868cb064a747f94 (patch)
treede5ec5926ba42722349854871871142205bd4c8b
parentAdd key import and export facility (diff)
downloadgpgme-a92ecd447027258e2674719bc868cb064a747f94.tar.gz
gpgme-a92ecd447027258e2674719bc868cb064a747f94.zip
Add key generation
Diffstat (limited to '')
-rw-r--r--gpgme/Makefile.am1
-rw-r--r--gpgme/context.h2
-rw-r--r--gpgme/data.c2
-rw-r--r--gpgme/export.c14
-rw-r--r--gpgme/genkey.c177
-rw-r--r--gpgme/gpgme.c1
-rw-r--r--gpgme/gpgme.h4
-rw-r--r--gpgme/rungpg.c4
-rw-r--r--tests/Makefile.am3
-rw-r--r--tests/t-genkey.c74
10 files changed, 278 insertions, 4 deletions
diff --git a/gpgme/Makefile.am b/gpgme/Makefile.am
index c7e4a732..32b72b4d 100644
--- a/gpgme/Makefile.am
+++ b/gpgme/Makefile.am
@@ -25,6 +25,7 @@ libgpgme_la_SOURCES = \
keylist.c \
import.c \
export.c \
+ genkey.c \
rungpg.c rungpg.h status-table.h \
syshdr.h io.h posix-io.c w32-io.c \
gpgme.c version.c errors.c
diff --git a/gpgme/context.h b/gpgme/context.h
index ba5a1b4a..6bba5372 100644
--- a/gpgme/context.h
+++ b/gpgme/context.h
@@ -71,6 +71,8 @@ struct gpgme_context_s {
GpgmePassphraseCb passphrase_cb;
void *passphrase_cb_value;
+
+ GpgmeData help_data_1;
};
diff --git a/gpgme/data.c b/gpgme/data.c
index 6581db4d..e63fd520 100644
--- a/gpgme/data.c
+++ b/gpgme/data.c
@@ -91,7 +91,7 @@ gpgme_data_new_from_mem ( GpgmeData *r_dh,
err = gpgme_data_new ( &dh );
if (err)
return err;
- dh->len = size;
+ dh->len = size;
if (copy) {
dh->private_buffer = xtrymalloc ( size );
if ( !dh->private_buffer ) {
diff --git a/gpgme/export.c b/gpgme/export.c
index ff6f3258..0265b46a 100644
--- a/gpgme/export.c
+++ b/gpgme/export.c
@@ -96,6 +96,20 @@ gpgme_op_export_start ( GpgmeCtx c, GpgmeRecipients recp,
+/**
+ * gpgme_op_export:
+ * @c: the context
+ * @recp: a list of recipients or NULL
+ * @keydata: Returns the keys
+ *
+ * This function can be used to extract public keys from the GnuPG key
+ * database either in armored (by using gpgme_set_armor()) or in plain
+ * binary form. The function expects a list of user IDs in @recp for
+ * whom the public keys are to be exportedkinit
+ *
+ *
+ * Return value: 0 for success or an error code
+ **/
GpgmeError
gpgme_op_export ( GpgmeCtx c, GpgmeRecipients recp, GpgmeData keydata )
{
diff --git a/gpgme/genkey.c b/gpgme/genkey.c
new file mode 100644
index 00000000..d0abae99
--- /dev/null
+++ b/gpgme/genkey.c
@@ -0,0 +1,177 @@
+/* genkey.c - key generation
+ * Copyright (C) 2000 Werner Koch (dd9jn)
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GPGME is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "util.h"
+#include "context.h"
+#include "ops.h"
+
+static void
+genkey_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
+{
+ if ( code == STATUS_PROGRESS )
+ return;
+
+ fprintf (stderr, "genkey_status: code=%d args=`%s'\n",
+ code, args );
+ /* FIXME: Need to do more */
+}
+
+
+
+/*
+ * Here is how the parms should be formatted:
+<GnupgKeyParms format="internal">
+Key-Type: DSA
+Key-Length: 1024
+Subkey-Type: ELG-E
+Subkey-Length: 1024
+Name-Real: Joe Tester
+Name-Comment: with stupid passphrase
+Name-Email: [email protected]
+Expire-Date: 0
+Passphrase: abc
+</GnupgKeyParms>
+ * Strings should be given in UTF-8 encoding. The format we support for now
+ * "internal". The content of the <GnupgKeyParms> container is passed
+ * verbatim to GnuPG. Control statements (e.g. %pubring) are not allowed.
+ */
+
+GpgmeError
+gpgme_op_genkey_start ( GpgmeCtx c, const char *parms,
+ GpgmeData pubkey, GpgmeData seckey )
+{
+ int rc = 0;
+ int i;
+ const char *s, *s2, *sx;
+
+ fail_on_pending_request( c );
+ c->pending = 1;
+
+ gpgme_data_release (c->help_data_1); c->help_data_1 = NULL;
+
+ /* create a process object */
+ _gpgme_gpg_release (c->gpg); c->gpg = NULL;
+ rc = _gpgme_gpg_new ( &c->gpg );
+ if (rc)
+ goto leave;
+
+ /* We need a special mechanism to get the fd of a pipe here, so
+ * that we can use this for the %pubring and %secring parameters.
+ * We don't have this yet, so we implement only the adding to the
+ * standard keyrings */
+ if ( pubkey || seckey ) {
+ rc = mk_error (Not_Implemented);
+ goto leave;
+ }
+
+ _gpgme_gpg_set_status_handler ( c->gpg, genkey_status_handler, c );
+
+ /* build the commandline */
+ _gpgme_gpg_add_arg ( c->gpg, "--gen-key" );
+ if ( c->use_armor )
+ _gpgme_gpg_add_arg ( c->gpg, "--armor" );
+ for ( i=0; i < c->verbosity; i++ )
+ _gpgme_gpg_add_arg ( c->gpg, "--verbose" );
+
+ if ( !pubkey && !seckey )
+ ; /* okay: Add key to the keyrings */
+ else if ( !pubkey
+ || gpgme_data_get_type (pubkey) != GPGME_DATA_TYPE_NONE ) {
+ rc = mk_error (Invalid_Value);
+ goto leave;
+ }
+ else if ( !seckey
+ || gpgme_data_get_type (seckey) != GPGME_DATA_TYPE_NONE ) {
+ rc = mk_error (Invalid_Value);
+ goto leave;
+ }
+
+ if ( pubkey ) {
+ _gpgme_data_set_mode (pubkey, GPGME_DATA_MODE_IN );
+ _gpgme_data_set_mode (seckey, GPGME_DATA_MODE_IN );
+ /* need some more things here */
+ }
+
+
+ if ( (parms = strstr (parms, "<GnupgKeyParms "))
+ && (s = strchr (parms, '>'))
+ && (sx = strstr (parms, "format=\"internal\""))
+ && sx < s
+ && (s2 = strstr (s+1, "</GnupgKeyParms>")) ) {
+ /* fixme: check that there are no control statements inside */
+ rc = gpgme_data_new_from_mem ( &c->help_data_1, s+1, s2-s-1, 1 );
+ }
+ else
+ rc = mk_error (Invalid_Value);
+
+ if (rc )
+ goto leave;
+
+ _gpgme_data_set_mode (c->help_data_1, GPGME_DATA_MODE_OUT );
+ _gpgme_gpg_add_data (c->gpg, c->help_data_1, 0);
+
+ rc = _gpgme_gpg_spawn ( c->gpg, c );
+
+ leave:
+ if (rc) {
+ c->pending = 0;
+ _gpgme_gpg_release ( c->gpg ); c->gpg = NULL;
+ }
+ return rc;
+}
+
+
+
+/**
+ * gpgme_op_genkey:
+ * @c: the context
+ * @parms: XML string with the key parameters
+ * @pubkey: Returns the public key
+ * @seckey: Returns the secret key
+ *
+ * Generate a new key and store the key in the default keyrings if both
+ * @pubkey and @seckey are NULL. If @pubkey and @seckey are given, the newly
+ * created key will be returned in these data objects.
+ * See gpgme_op_genkey_start() for a description of @parms.
+ *
+ * Return value: 0 for success or an error code
+ **/
+GpgmeError
+gpgme_op_genkey( GpgmeCtx c, const char *parms,
+ GpgmeData pubkey, GpgmeData seckey )
+{
+ int rc = gpgme_op_genkey_start ( c, parms, pubkey, seckey );
+ if ( !rc ) {
+ gpgme_wait (c, 1);
+ c->pending = 0;
+ }
+ return rc;
+}
+
+
+
+
+
diff --git a/gpgme/gpgme.c b/gpgme/gpgme.c
index 931e78f9..23eef199 100644
--- a/gpgme/gpgme.c
+++ b/gpgme/gpgme.c
@@ -70,6 +70,7 @@ gpgme_release ( GpgmeCtx c )
_gpgme_gpg_release ( c->gpg );
_gpgme_release_result ( c );
_gpgme_key_release ( c->tmp_key );
+ gpgme_data_release ( c->help_data_1 );
gpgme_data_release ( c->notation );
/* fixme: release the key_queue */
xfree (c);
diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h
index 99c39524..e4f1e95a 100644
--- a/gpgme/gpgme.h
+++ b/gpgme/gpgme.h
@@ -163,6 +163,8 @@ GpgmeError gpgme_op_verify_start ( GpgmeCtx c,
GpgmeError gpgme_op_import_start ( GpgmeCtx c, GpgmeData keydata );
GpgmeError gpgme_op_export_start ( GpgmeCtx c, GpgmeRecipients recp,
GpgmeData keydata );
+GpgmeError gpgme_op_genkey_start ( GpgmeCtx c, const char *parms,
+ GpgmeData pubkey, GpgmeData seckey );
@@ -185,6 +187,8 @@ GpgmeError gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,
GpgmeError gpgme_op_import ( GpgmeCtx c, GpgmeData keydata );
GpgmeError gpgme_op_export ( GpgmeCtx c, GpgmeRecipients recp,
GpgmeData keydata );
+GpgmeError gpgme_op_genkey ( GpgmeCtx c, const char *parms,
+ GpgmeData pubkey, GpgmeData seckey );
/* miscellaneous functions */
diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c
index dde29a37..07231716 100644
--- a/gpgme/rungpg.c
+++ b/gpgme/rungpg.c
@@ -438,7 +438,7 @@ free_fd_data_map ( struct fd_data_map_s *fd_data_map )
if ( fd_data_map[i].peer_fd != -1 )
_gpgme_io_close (fd_data_map[i].peer_fd);
#endif
- /* don't realease data because this is only a reference */
+ /* don't release data because this is only a reference */
}
xfree (fd_data_map);
}
@@ -962,7 +962,7 @@ read_status ( GpgObject gpg )
if ( *p == '\n' ) {
/* (we require that the last line is terminated by a LF) */
*p = 0;
- fprintf (stderr, "read_status: `%s'\n", buffer);
+ /*fprintf (stderr, "read_status: `%s'\n", buffer);*/
if (!strncmp (buffer, "[GNUPG:] ", 9 )
&& buffer[9] >= 'A' && buffer[9] <= 'Z' ) {
struct status_table_s t, *r;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 1d69ad7e..3f5f2349 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -2,7 +2,8 @@
TESTS_ENVIRONMENT = GNUPGHOME=.
-TESTS = t-encrypt t-sign t-decrypt t-verify t-keylist t-export t-import
+TESTS = t-encrypt t-sign t-decrypt t-verify t-keylist t-export t-import \
+ t-genkey
EXTRA_DIST = mkdemodirs pubdemo.asc secdemo.asc cipher-1.asc geheim.txt \
pubkey-1.asc seckey-1.asc
diff --git a/tests/t-genkey.c b/tests/t-genkey.c
new file mode 100644
index 00000000..710dfa0b
--- /dev/null
+++ b/tests/t-genkey.c
@@ -0,0 +1,74 @@
+/* t-genkey.c - regression test
+ * Copyright (C) 2000 Werner Koch (dd9jn)
+ *
+ * This file is part of GPGME.
+ *
+ * GPGME is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GPGME is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "../gpgme/gpgme.h"
+
+#define fail_if_err(a) do { if(a) { \
+ fprintf (stderr, "%s:%d: GpgmeError %s\n", \
+ __FILE__, __LINE__, gpgme_strerror(a)); \
+ exit (1); } \
+ } while(0)
+
+
+int
+main (int argc, char **argv )
+{
+ GpgmeCtx ctx;
+ GpgmeError err;
+ const char *format;
+ char *parms;
+ int count = 0;
+
+ do {
+ err = gpgme_new (&ctx);
+ fail_if_err (err);
+
+ format = "<GnupgKeyParms format=\"internal\">\n"
+ "Key-Type: DSA\n"
+ "Key-Length: 1024\n"
+ "Subkey-Type: ELG-E\n"
+ "Subkey-Length: 1024\n"
+ "Name-Real: Joe Tester\n"
+ "Name-Comment: (pp=abc,try=%d)\n"
+ "Name-Email: [email protected]\n"
+ "Expire-Date: 0\n"
+ "Passphrase: abc\n"
+ "</GnupgKeyParms>\n";
+ parms = malloc ( strlen (format) + 1 + 20 );
+ if (!parms)
+ exit (8);
+ sprintf (parms, format, ++count );
+ err = gpgme_op_genkey (ctx, parms, NULL, NULL );
+ fail_if_err (err);
+ free (parms);
+
+ gpgme_release (ctx);
+ } while ( argc > 1 && !strcmp( argv[1], "--loop" ) );
+
+ return 0;
+}
+
+
+