diff options
Diffstat (limited to 'gpglib/genkey.c')
| -rw-r--r-- | gpglib/genkey.c | 209 | 
1 files changed, 209 insertions, 0 deletions
| diff --git a/gpglib/genkey.c b/gpglib/genkey.c new file mode 100644 index 0000000..9e72f1c --- /dev/null +++ b/gpglib/genkey.c @@ -0,0 +1,209 @@ +/* +** Copyright 2001-2011 Double Precision, Inc.  See COPYING for +** distribution information. +*/ + + +#include	"config.h" +#include	<stdio.h> +#include	<stdlib.h> +#include	<string.h> +#include	<unistd.h> +#include	<signal.h> +#include	<errno.h> +#include	<sys/types.h> +#include	<sys/stat.h> +#include	<sys/time.h> + +#include	"gpg.h" +#include	"gpglib.h" + +#include	"unicode/unicode.h" +#include	"numlib/numlib.h" + +extern int libmail_gpg_stdin, libmail_gpg_stdout, libmail_gpg_stderr; +extern pid_t libmail_gpg_pid; + + +/* +** Generate a new key. +*/ + +static int dogenkey(const char *, const char *, const char *, +		    int, +		    int, +		    unsigned, +		    char, +		    const char *passphrase, +		    int (*)(const char *, size_t, void *), +		    int (*)(void *), +		    void *); + +int libmail_gpg_genkey(const char *gpgdir, +		       const char *charset, +		       const char *name, +		       const char *addr, +		       const char *comment, +		       int skeylen, +		       int ekeylen, +		       unsigned expire, +		       char expire_unit, +		       const char *passphrase, +		       int (*dump_func)(const char *, size_t, void *), +		       int (*timeout_func)(void *), +		       void *voidarg) +{ +	char *name_u, *addr_u, *comment_u; +	char *argvec[4]; +	int rc; + +	name_u=libmail_u_convert_toutf8(name, charset, NULL); + +	if (!name_u) +		return (-1); + +	addr_u=libmail_u_convert_toutf8(addr, charset, NULL); +	if (!addr_u) +	{ +		free(name_u); +		return (-1); +	} + +	comment_u=libmail_u_convert_toutf8(comment, charset, NULL); +	if (!comment_u) +		return (-1); + + +	argvec[0]="gpg"; +	argvec[1]="--gen-key"; +	argvec[2]="--batch"; +	argvec[3]=NULL; + +	if (libmail_gpg_fork(&libmail_gpg_stdin, &libmail_gpg_stdout, NULL, +			     gpgdir, argvec) < 0) +		rc= -1; +	else +	{ +		int rc2; + +		rc=dogenkey(name_u, addr_u, comment_u, +			    skeylen, ekeylen, expire, expire_unit, +			    passphrase, +			    dump_func, timeout_func, voidarg); +		rc2=libmail_gpg_cleanup(); +		if (rc2) +			rc=rc2; +	} +	free(comment_u); +	free(name_u); +	free(addr_u); +	return (rc); +} + +static char *mkcmdbuf(const char *, const char *, const char *, +		      int, +		      int, +		      unsigned, +		      char, const char *); + +static int dogenkey(const char *name, const char *addr, const char *comment, +		    int skeylen, +		    int ekeylen, +		    unsigned expire, +		    char expire_unit, +		    const char *passphrase, +		    int (*dump_func)(const char *, size_t, void *), +		    int (*timeout_func)(void *), +		    void *voidarg) +{ +	char *cmd_buf=mkcmdbuf(name, addr, comment, skeylen, ekeylen, +			       expire, expire_unit, passphrase); + +	int rc=libmail_gpg_write(cmd_buf, strlen(cmd_buf), dump_func, NULL, +			 timeout_func, 5, voidarg); +	int rc2; + +	free(cmd_buf); +	if (rc == 0) +		rc=libmail_gpg_read(dump_func, NULL, timeout_func, 5, voidarg); +	rc2=libmail_gpg_cleanup(); +	if (rc == 0) +		rc=rc2; +	return (rc); +} + +static char *mkcmdbuf(const char *name, const char *addr, const char *comment, +		      int skeylen, +		      int ekeylen, +		      unsigned expire, +		      char expire_unit, +		      const char *passphrase) +{ +	static const char genkey_cmd[]= +		"Key-Type: DSA\n" +		"Key-Length: %s\n" +		"Subkey-Type: ELG-E\n" +		"Subkey-Length: %s\n" +		"%s%s%s" +		"%s%s%s" +		"%s%s%s" +		"Name-Email: %s\n" +		"Expire-Date: %s\n" +		"%%commit\n"; + +	static const char namereal1[]="Name-Real: "; +	static const char namereal2[]="\n"; +	static const char comment1[]="Name-Comment: "; +	static const char comment2[]="\n"; +	static const char passphrase1[]="Passphrase: "; +	static const char passphrase2[]="\n"; + +	char skl_buf[NUMBUFSIZE]; +	char kl_buf[NUMBUFSIZE]; +	char exp_buf[NUMBUFSIZE+1]; + +	char *p; + +	libmail_str_size_t(skeylen, skl_buf); +	libmail_str_size_t(ekeylen, kl_buf); +	if (expire == 0) +	{ +		strcpy(exp_buf, "0"); +	} +	else +	{ +		char b[2]; + +		b[0]=expire_unit; +		b[1]=0; + +		strcat(libmail_str_size_t(expire, exp_buf), b); +	} + +	p=malloc(512+strlen(kl_buf)+strlen(skl_buf)+strlen(exp_buf) +		 +strlen(name)+strlen(addr)+strlen(comment) +		 +strlen(passphrase)); + +	if (!p) +		return (NULL); + +	while (*comment == ' ' || *comment == '\t') +		++comment; + +	sprintf(p, genkey_cmd, skl_buf, kl_buf, + +		*name ? namereal1:"", +		name, +		*name ? namereal2:"", + +		*comment ? comment1:"", +		comment, +		*comment ? comment2:"", + +		*passphrase ? passphrase1:"", +		passphrase, +		*passphrase ? passphrase2:"", + +		addr, exp_buf); +	return (p); +} | 
