mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-23 15:07:03 +01:00
* base64.c (gpgsm_create_writer): Allow to set the object name
* server.c (cmd_genkey): New. * certreqgen.c: New. The parameter handling code has been taken from gnupg/g10/keygen.c version 1.0.6. * call-agent.c (gpgsm_agent_genkey): New.
This commit is contained in:
parent
8bad9e344b
commit
dc37fe1849
20
sm/ChangeLog
20
sm/ChangeLog
@ -1,3 +1,21 @@
|
|||||||
|
2002-01-10 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* base64.c (gpgsm_create_writer): Allow to set the object name
|
||||||
|
|
||||||
|
2002-01-08 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* keydb.c (spacep): Removed because it is now in util.c
|
||||||
|
|
||||||
|
* server.c (cmd_genkey): New.
|
||||||
|
* certreqgen.c: New. The parameter handling code has been taken
|
||||||
|
from gnupg/g10/keygen.c version 1.0.6.
|
||||||
|
* call-agent.c (gpgsm_agent_genkey): New.
|
||||||
|
|
||||||
|
2002-01-02 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* server.c (rc_to_assuan_status): Removed and changed all callers
|
||||||
|
to use map_to_assuan_status.
|
||||||
|
|
||||||
2001-12-20 Werner Koch <wk@gnupg.org>
|
2001-12-20 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* verify.c (gpgsm_verify): Implemented non-detached signature
|
* verify.c (gpgsm_verify): Implemented non-detached signature
|
||||||
@ -126,7 +144,7 @@
|
|||||||
* server.c (rc_to_assuan_status): New. Use it for all commands.
|
* server.c (rc_to_assuan_status): New. Use it for all commands.
|
||||||
|
|
||||||
|
|
||||||
Copyright 2001 Free Software Foundation, Inc.
|
Copyright 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is free software; as a special exception the author gives
|
This file is free software; as a special exception the author gives
|
||||||
unlimited permission to copy and/or distribute it, with or without
|
unlimited permission to copy and/or distribute it, with or without
|
||||||
|
@ -41,7 +41,8 @@ gpgsm_SOURCES = \
|
|||||||
sign.c \
|
sign.c \
|
||||||
encrypt.c \
|
encrypt.c \
|
||||||
decrypt.c \
|
decrypt.c \
|
||||||
import.c
|
import.c \
|
||||||
|
certreqgen.c
|
||||||
|
|
||||||
|
|
||||||
gpgsm_LDADD = ../jnlib/libjnlib.a ../assuan/libassuan.a ../kbx/libkeybox.a \
|
gpgsm_LDADD = ../jnlib/libjnlib.a ../assuan/libassuan.a ../kbx/libkeybox.a \
|
||||||
|
@ -581,7 +581,8 @@ gpgsm_create_writer (Base64Context *ctx,
|
|||||||
{
|
{
|
||||||
(*ctx)->u.wparm.fp = fp;
|
(*ctx)->u.wparm.fp = fp;
|
||||||
if (ctrl->create_pem)
|
if (ctrl->create_pem)
|
||||||
(*ctx)->u.wparm.pem_name = "CMS OBJECT"; /* fixme */
|
(*ctx)->u.wparm.pem_name = ctrl->pem_name? ctrl->pem_name
|
||||||
|
: "CMS OBJECT";
|
||||||
rc = ksba_writer_set_cb (w, base64_writer_cb, &(*ctx)->u.wparm);
|
rc = ksba_writer_set_cb (w, base64_writer_cb, &(*ctx)->u.wparm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -52,6 +52,12 @@ struct cipher_parm_s {
|
|||||||
size_t ciphertextlen;
|
size_t ciphertextlen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct genkey_parm_s {
|
||||||
|
ASSUAN_CONTEXT ctx;
|
||||||
|
const char *sexp;
|
||||||
|
size_t sexplen;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct membuf {
|
struct membuf {
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -250,6 +256,9 @@ gpgsm_agent_pksign (const char *keygrip,
|
|||||||
return map_assuan_err (rc);
|
return map_assuan_err (rc);
|
||||||
}
|
}
|
||||||
*r_buf = get_membuf (&data, r_buflen);
|
*r_buf = get_membuf (&data, r_buflen);
|
||||||
|
|
||||||
|
/* FIXME: check that the returned S-Exp is valid! */
|
||||||
|
|
||||||
return *r_buf? 0 : GNUPG_Out_Of_Core;
|
return *r_buf? 0 : GNUPG_Out_Of_Core;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,6 +350,65 @@ gpgsm_agent_pkdecrypt (const char *keygrip,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Handle a KEYPARMS inquiry. Note, we only send the data,
|
||||||
|
assuan_transact takes care of flushing and writing the end */
|
||||||
|
static AssuanError
|
||||||
|
inq_genkey_parms (void *opaque, const char *keyword)
|
||||||
|
{
|
||||||
|
struct genkey_parm_s *parm = opaque;
|
||||||
|
AssuanError rc;
|
||||||
|
|
||||||
|
rc = assuan_send_data (parm->ctx, parm->sexp, parm->sexplen);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Call the agent to generate a newkey */
|
||||||
|
int
|
||||||
|
gpgsm_agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
struct genkey_parm_s gk_parm;
|
||||||
|
struct membuf data;
|
||||||
|
size_t len;
|
||||||
|
char *buf;
|
||||||
|
|
||||||
|
*r_pubkey = NULL;
|
||||||
|
rc = start_agent ();
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL);
|
||||||
|
if (rc)
|
||||||
|
return map_assuan_err (rc);
|
||||||
|
|
||||||
|
init_membuf (&data, 1024);
|
||||||
|
gk_parm.ctx = agent_ctx;
|
||||||
|
gk_parm.sexp = keyparms;
|
||||||
|
gk_parm.sexplen = gcry_sexp_canon_len (keyparms, 0, NULL, NULL);
|
||||||
|
if (!gk_parm.sexplen)
|
||||||
|
return GNUPG_Invalid_Value;
|
||||||
|
rc = assuan_transact (agent_ctx, "GENKEY",
|
||||||
|
membuf_data_cb, &data,
|
||||||
|
inq_genkey_parms, &gk_parm);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
xfree (get_membuf (&data, &len));
|
||||||
|
return map_assuan_err (rc);
|
||||||
|
}
|
||||||
|
buf = get_membuf (&data, &len);
|
||||||
|
if (!buf)
|
||||||
|
return GNUPG_Out_Of_Core;
|
||||||
|
if (!gcry_sexp_canon_len (buf, len, NULL, NULL))
|
||||||
|
{
|
||||||
|
xfree (buf);
|
||||||
|
return GNUPG_Invalid_Sexp;
|
||||||
|
}
|
||||||
|
*r_pubkey = buf;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
651
sm/certreqgen.c
Normal file
651
sm/certreqgen.c
Normal file
@ -0,0 +1,651 @@
|
|||||||
|
/* certreqgen.c - Generate a key and a certification request
|
||||||
|
* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG 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.
|
||||||
|
*
|
||||||
|
* GnuPG 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The format of the native parameter file is follows:
|
||||||
|
o Text only, line length is limited to about 1000 chars.
|
||||||
|
o You must use UTF-8 encoding to specify non-ascii characters.
|
||||||
|
o Empty lines are ignored.
|
||||||
|
o Leading and trailing spaces are ignored.
|
||||||
|
o A hash sign as the first non white space character is a comment line.
|
||||||
|
o Control statements are indicated by a leading percent sign, the
|
||||||
|
arguments are separated by white space from the keyword.
|
||||||
|
o Parameters are specified by a keyword, followed by a colon. Arguments
|
||||||
|
are separated by white space.
|
||||||
|
o The first parameter must be "Key-Type", control statements
|
||||||
|
may be placed anywhere.
|
||||||
|
o Key generation takes place when either the end of the parameter file
|
||||||
|
is reached, the next "Key-Type" parameter is encountered or at the
|
||||||
|
controlstatement "%commit"
|
||||||
|
o Control statements:
|
||||||
|
%echo <text>
|
||||||
|
Print <text>.
|
||||||
|
%dry-run
|
||||||
|
Suppress actual key generation (useful for syntax checking).
|
||||||
|
%commit
|
||||||
|
Perform the key generation. Note that an implicit commit is done
|
||||||
|
at the next "Key-Type" parameter.
|
||||||
|
%certfile <filename>
|
||||||
|
Do not write the certificate to the keyDB but to <filename>.
|
||||||
|
This must be given before the first
|
||||||
|
commit to take place, duplicate specification of the same filename
|
||||||
|
is ignored, the last filename before a commit is used.
|
||||||
|
The filename is used until a new filename is used (at commit points)
|
||||||
|
and all keys are written to that file. If a new filename is given,
|
||||||
|
this file is created (and overwrites an existing one).
|
||||||
|
Both control statements must be given.
|
||||||
|
o The order of the parameters does not matter except for "Key-Type"
|
||||||
|
which must be the first parameter. The parameters are only for the
|
||||||
|
generated keyblock and parameters from previous key generations are not
|
||||||
|
used. Some syntactically checks may be performed.
|
||||||
|
The currently defined parameters are:
|
||||||
|
Key-Type: <algo>
|
||||||
|
Starts a new parameter block by giving the type of the
|
||||||
|
primary key. The algorithm must be capable of signing.
|
||||||
|
This is a required parameter. For now the only supported
|
||||||
|
algorithm is "rsa".
|
||||||
|
Key-Length: <length-in-bits>
|
||||||
|
Length of the key in bits. Default is 1024.
|
||||||
|
Key-Usage: <usage-list>
|
||||||
|
Space or comma delimited list of key usage, allowed values are
|
||||||
|
"encrypt" and "sign". This is used to generate the KeyUsage extension.
|
||||||
|
Please make sure that the algorithm is capable of this usage. Default
|
||||||
|
is to allow encrypt and sign.
|
||||||
|
Name-DN: subject name
|
||||||
|
This is the DN name of the subject in rfc2253 format.
|
||||||
|
Name-Email: <string>
|
||||||
|
The ist the email address
|
||||||
|
|
||||||
|
Here is an example:
|
||||||
|
$ cat >foo <<EOF
|
||||||
|
%echo Generating a standard key
|
||||||
|
Key-Type: RSA
|
||||||
|
Key-Length: 1024
|
||||||
|
Name-DN: CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Düsseldorf,C=DE
|
||||||
|
Name-Email: joe@foo.bar
|
||||||
|
# Do a commit here, so that we can later print "done" :-)
|
||||||
|
%commit
|
||||||
|
%echo done
|
||||||
|
EOF
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <gcrypt.h>
|
||||||
|
#include <ksba.h>
|
||||||
|
|
||||||
|
#include "gpgsm.h"
|
||||||
|
#include "keydb.h"
|
||||||
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
||||||
|
enum para_name {
|
||||||
|
pKEYTYPE,
|
||||||
|
pKEYLENGTH,
|
||||||
|
pKEYUSAGE,
|
||||||
|
pNAMEDN,
|
||||||
|
pNAMEEMAIL
|
||||||
|
};
|
||||||
|
|
||||||
|
struct para_data_s {
|
||||||
|
struct para_data_s *next;
|
||||||
|
int lnr;
|
||||||
|
enum para_name key;
|
||||||
|
union {
|
||||||
|
unsigned int usage;
|
||||||
|
char value[1];
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct reqgen_ctrl_s {
|
||||||
|
int lnr;
|
||||||
|
int dryrun;
|
||||||
|
KsbaWriter writer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int proc_parameters (struct para_data_s *para,
|
||||||
|
struct reqgen_ctrl_s *outctrl);
|
||||||
|
static int create_request (struct para_data_s *para,
|
||||||
|
KsbaConstSexp public,
|
||||||
|
struct reqgen_ctrl_s *outctrl);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
release_parameter_list (struct para_data_s *r)
|
||||||
|
{
|
||||||
|
struct para_data_s *r2;
|
||||||
|
|
||||||
|
for (; r ; r = r2)
|
||||||
|
{
|
||||||
|
r2 = r->next;
|
||||||
|
xfree(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct para_data_s *
|
||||||
|
get_parameter (struct para_data_s *para, enum para_name key)
|
||||||
|
{
|
||||||
|
struct para_data_s *r;
|
||||||
|
|
||||||
|
for (r = para; r && r->key != key; r = r->next)
|
||||||
|
;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
get_parameter_value (struct para_data_s *para, enum para_name key)
|
||||||
|
{
|
||||||
|
struct para_data_s *r = get_parameter (para, key);
|
||||||
|
return (r && *r->u.value)? r->u.value : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_parameter_algo (struct para_data_s *para, enum para_name key)
|
||||||
|
{
|
||||||
|
struct para_data_s *r = get_parameter (para, key);
|
||||||
|
if (!r)
|
||||||
|
return -1;
|
||||||
|
if (digitp (r->u.value))
|
||||||
|
return atoi( r->u.value );
|
||||||
|
return gcry_pk_map_name (r->u.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse the usage parameter. Returns 0 on success. Note that we
|
||||||
|
only care about sign and encrypt and don't (yet) allow all the
|
||||||
|
other X.509 usage to be specified; instead we will use a fixed
|
||||||
|
mapping to the X.509 usage flags */
|
||||||
|
static int
|
||||||
|
parse_parameter_usage (struct para_data_s *para, enum para_name key)
|
||||||
|
{
|
||||||
|
struct para_data_s *r = get_parameter (para, key);
|
||||||
|
char *p, *pn;
|
||||||
|
unsigned int use;
|
||||||
|
|
||||||
|
if (!r)
|
||||||
|
return 0; /* none (this is an optional parameter)*/
|
||||||
|
|
||||||
|
use = 0;
|
||||||
|
pn = r->u.value;
|
||||||
|
while ( (p = strsep (&pn, " \t,")) )
|
||||||
|
{
|
||||||
|
if (!*p)
|
||||||
|
;
|
||||||
|
else if ( !ascii_strcasecmp (p, "sign") )
|
||||||
|
use |= GCRY_PK_USAGE_SIGN;
|
||||||
|
else if ( !ascii_strcasecmp (p, "encrypt") )
|
||||||
|
use |= GCRY_PK_USAGE_ENCR;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_error ("line %d: invalid usage list\n", r->lnr);
|
||||||
|
return -1; /* error */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r->u.usage = use;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned int
|
||||||
|
get_parameter_uint (struct para_data_s *para, enum para_name key)
|
||||||
|
{
|
||||||
|
struct para_data_s *r = get_parameter (para, key);
|
||||||
|
|
||||||
|
if (!r)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (unsigned int)strtoul (r->u.value, NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Read the certificate generation parameters from FP and genereate
|
||||||
|
(all) certificate requests. */
|
||||||
|
static int
|
||||||
|
read_parameters (FILE *fp, KsbaWriter writer)
|
||||||
|
{
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
enum para_name key;
|
||||||
|
} keywords[] = {
|
||||||
|
{ "Key-Type", pKEYTYPE},
|
||||||
|
{ "Key-Length", pKEYLENGTH },
|
||||||
|
{ "Key-Usage", pKEYUSAGE },
|
||||||
|
{ "Name-DN", pNAMEDN },
|
||||||
|
{ "Name-Email", pNAMEEMAIL },
|
||||||
|
{ NULL, 0 }
|
||||||
|
};
|
||||||
|
char line[1024], *p;
|
||||||
|
const char *err = NULL;
|
||||||
|
struct para_data_s *para, *r;
|
||||||
|
int i;
|
||||||
|
struct reqgen_ctrl_s outctrl;
|
||||||
|
|
||||||
|
memset (&outctrl, 0, sizeof (outctrl));
|
||||||
|
outctrl.writer = writer;
|
||||||
|
|
||||||
|
err = NULL;
|
||||||
|
para = NULL;
|
||||||
|
while (fgets (line, DIM(line)-1, fp) )
|
||||||
|
{
|
||||||
|
char *keyword, *value;
|
||||||
|
|
||||||
|
outctrl.lnr++;
|
||||||
|
if (*line && line[strlen(line)-1] != '\n')
|
||||||
|
{
|
||||||
|
err = "line too long";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (p=line; spacep (p); p++)
|
||||||
|
;
|
||||||
|
if (!*p || *p == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
keyword = p;
|
||||||
|
if (*keyword == '%')
|
||||||
|
{
|
||||||
|
for (; !spacep (p); p++)
|
||||||
|
;
|
||||||
|
if (*p)
|
||||||
|
*p++ = 0;
|
||||||
|
for (; spacep (p); p++)
|
||||||
|
;
|
||||||
|
value = p;
|
||||||
|
trim_trailing_spaces (value);
|
||||||
|
|
||||||
|
if (!ascii_strcasecmp (keyword, "%echo"))
|
||||||
|
log_info ("%s\n", value);
|
||||||
|
else if (!ascii_strcasecmp (keyword, "%dry-run"))
|
||||||
|
outctrl.dryrun = 1;
|
||||||
|
else if (!ascii_strcasecmp( keyword, "%commit"))
|
||||||
|
{
|
||||||
|
proc_parameters (para, &outctrl);
|
||||||
|
/*FIXME: what about error handling */
|
||||||
|
release_parameter_list (para);
|
||||||
|
para = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log_info ("skipping control `%s' (%s)\n", keyword, value);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!(p = strchr (p, ':')) || p == keyword)
|
||||||
|
{
|
||||||
|
err = "missing colon";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (*p)
|
||||||
|
*p++ = 0;
|
||||||
|
for (; spacep (p); p++)
|
||||||
|
;
|
||||||
|
if (!*p)
|
||||||
|
{
|
||||||
|
err = "missing argument";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
value = p;
|
||||||
|
trim_trailing_spaces (value);
|
||||||
|
|
||||||
|
for (i=0; (keywords[i].name
|
||||||
|
&& ascii_strcasecmp (keywords[i].name, keyword)); i++)
|
||||||
|
;
|
||||||
|
if (!keywords[i].name)
|
||||||
|
{
|
||||||
|
err = "unknown keyword";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (keywords[i].key != pKEYTYPE && !para)
|
||||||
|
{
|
||||||
|
err = "parameter block does not start with \"Key-Type\"";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keywords[i].key == pKEYTYPE && para)
|
||||||
|
{
|
||||||
|
proc_parameters (para, &outctrl);
|
||||||
|
release_parameter_list (para);
|
||||||
|
para = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (r = para; r && r->key != keywords[i].key; r = r->next)
|
||||||
|
;
|
||||||
|
if (r)
|
||||||
|
{
|
||||||
|
err = "duplicate keyword";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r = xtrycalloc (1, sizeof *r + strlen( value ));
|
||||||
|
if (!r)
|
||||||
|
{
|
||||||
|
err = "out of core";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
r->lnr = outctrl.lnr;
|
||||||
|
r->key = keywords[i].key;
|
||||||
|
strcpy (r->u.value, value);
|
||||||
|
r->next = para;
|
||||||
|
para = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err)
|
||||||
|
log_error ("line %d: %s\n", outctrl.lnr, err);
|
||||||
|
else if (ferror(fp))
|
||||||
|
log_error ("line %d: read error: %s\n", outctrl.lnr, strerror(errno) );
|
||||||
|
else if (para)
|
||||||
|
{
|
||||||
|
proc_parameters (para, &outctrl);
|
||||||
|
/*FIXME: what about error handling */
|
||||||
|
}
|
||||||
|
|
||||||
|
release_parameter_list (para);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check whether there are invalid characters in the email address S */
|
||||||
|
static int
|
||||||
|
has_invalid_email_chars (const char *s)
|
||||||
|
{
|
||||||
|
int at_seen=0;
|
||||||
|
static char valid_chars[] = "01234567890_-."
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
for (; *s; s++)
|
||||||
|
{
|
||||||
|
if (*s & 0x80)
|
||||||
|
return 1;
|
||||||
|
if (*s == '@')
|
||||||
|
at_seen++;
|
||||||
|
else if (!at_seen && !( !!strchr (valid_chars, *s) || *s == '+'))
|
||||||
|
return 1;
|
||||||
|
else if (at_seen && !strchr (valid_chars, *s))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return at_seen != 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Check that all required parameters are given and perform the action */
|
||||||
|
static int
|
||||||
|
proc_parameters (struct para_data_s *para, struct reqgen_ctrl_s *outctrl)
|
||||||
|
{
|
||||||
|
struct para_data_s *r;
|
||||||
|
const char *s;
|
||||||
|
int i;
|
||||||
|
unsigned int nbits;
|
||||||
|
char numbuf[20];
|
||||||
|
unsigned char keyparms[100];
|
||||||
|
int rc;
|
||||||
|
KsbaSexp public;
|
||||||
|
|
||||||
|
/* check that we have all required parameters */
|
||||||
|
assert (get_parameter (para, pKEYTYPE));
|
||||||
|
|
||||||
|
/* We can only use RSA for now. There is a with pkcs-10 on how to
|
||||||
|
use ElGamal becuase it is expected that a PK algorithm can always
|
||||||
|
be used for signing. */
|
||||||
|
i = get_parameter_algo (para, pKEYTYPE);
|
||||||
|
if (i < 1 || i != GCRY_PK_RSA )
|
||||||
|
{
|
||||||
|
r = get_parameter (para, pKEYTYPE);
|
||||||
|
log_error ("line %d: invalid algorithm\n", r->lnr);
|
||||||
|
return GNUPG_Invalid_Parameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check the keylength */
|
||||||
|
if (!get_parameter (para, pKEYLENGTH))
|
||||||
|
nbits = 1024;
|
||||||
|
else
|
||||||
|
nbits = get_parameter_uint (para, pKEYLENGTH);
|
||||||
|
if (nbits < 512 || nbits > 4096)
|
||||||
|
{
|
||||||
|
r = get_parameter (para, pKEYTYPE);
|
||||||
|
log_error ("line %d: invalid key length %u (valid are 512 to 4096)\n",
|
||||||
|
r->lnr, nbits);
|
||||||
|
return GNUPG_Invalid_Parameter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check the usage */
|
||||||
|
if (parse_parameter_usage (para, pKEYUSAGE))
|
||||||
|
return GNUPG_Invalid_Parameter;
|
||||||
|
|
||||||
|
/* check that there is a subject name and that this DN fits our
|
||||||
|
requirements */
|
||||||
|
if (!(s=get_parameter_value (para, pNAMEDN)))
|
||||||
|
{
|
||||||
|
r = get_parameter (para, pKEYTYPE);
|
||||||
|
log_error ("line %d: no subject name given\n", r->lnr);
|
||||||
|
return GNUPG_Invalid_Parameter;
|
||||||
|
}
|
||||||
|
/* fixme check s */
|
||||||
|
|
||||||
|
/* check that the optional email address is okay */
|
||||||
|
if ((s=get_parameter_value (para, pNAMEEMAIL)))
|
||||||
|
{
|
||||||
|
if (has_invalid_email_chars (s)
|
||||||
|
|| *s == '@'
|
||||||
|
|| s[strlen(s)-1] == '@'
|
||||||
|
|| s[strlen(s)-1] == '.'
|
||||||
|
|| strstr(s, ".."))
|
||||||
|
{
|
||||||
|
r = get_parameter (para, pKEYTYPE);
|
||||||
|
log_error ("line %d: not a valid email address\n", r->lnr);
|
||||||
|
return GNUPG_Invalid_Parameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf (numbuf, "%u", nbits);
|
||||||
|
snprintf (keyparms, DIM (keyparms)-1,
|
||||||
|
"(6:genkey(3:rsa(5:nbits%d:%s)))", strlen (numbuf), numbuf);
|
||||||
|
rc = gpgsm_agent_genkey (keyparms, &public);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
r = get_parameter (para, pKEYTYPE);
|
||||||
|
log_error ("line %d: key generation failed: %s\n",
|
||||||
|
r->lnr, gnupg_strerror (rc));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = create_request (para, public, outctrl);
|
||||||
|
xfree (public);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Parameters are checked, the key pair has been created. Now
|
||||||
|
generate the request and write it out */
|
||||||
|
static int
|
||||||
|
create_request (struct para_data_s *para, KsbaConstSexp public,
|
||||||
|
struct reqgen_ctrl_s *outctrl)
|
||||||
|
{
|
||||||
|
KsbaCertreq cr;
|
||||||
|
KsbaError err;
|
||||||
|
GCRY_MD_HD md;
|
||||||
|
KsbaStopReason stopreason;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
cr = ksba_certreq_new ();
|
||||||
|
if (!cr)
|
||||||
|
return seterr (Out_Of_Core);
|
||||||
|
|
||||||
|
md = gcry_md_open (GCRY_MD_SHA1, 0);
|
||||||
|
if (!md)
|
||||||
|
{
|
||||||
|
log_error ("md_open failed: %s\n", gcry_strerror (-1));
|
||||||
|
rc = map_gcry_err (gcry_errno ());
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
if (DBG_HASHING)
|
||||||
|
gcry_md_start_debug (md, "cr.cri");
|
||||||
|
|
||||||
|
ksba_certreq_set_hash_function (cr, HASH_FNC, md);
|
||||||
|
ksba_certreq_set_writer (cr, outctrl->writer);
|
||||||
|
|
||||||
|
err = ksba_certreq_set_subject (cr, get_parameter_value (para, pNAMEDN));
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("error setting the subject's name: %s\n",
|
||||||
|
ksba_strerror (err));
|
||||||
|
rc = map_ksba_err (err);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ksba_certreq_set_public_key (cr, public);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("error setting the public key: %s\n",
|
||||||
|
ksba_strerror (err));
|
||||||
|
rc = map_ksba_err (err);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
err = ksba_certreq_build (cr, &stopreason);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("ksba_certreq_build failed: %s\n", ksba_strerror (err));
|
||||||
|
rc = map_ksba_err (err);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
if (stopreason == KSBA_SR_NEED_SIG)
|
||||||
|
{
|
||||||
|
GCRY_SEXP s_pkey;
|
||||||
|
size_t n;
|
||||||
|
unsigned char grip[20], hexgrip[41];
|
||||||
|
char *sigval;
|
||||||
|
size_t siglen;
|
||||||
|
|
||||||
|
n = gcry_sexp_canon_len (public, 0, NULL, NULL);
|
||||||
|
if (!n)
|
||||||
|
{
|
||||||
|
log_error ("libksba did not return a proper S-Exp\n");
|
||||||
|
err = GNUPG_Bug;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
rc = gcry_sexp_sscan (&s_pkey, NULL, public, n);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error ("gcry_sexp_scan failed: %s\n", gcry_strerror (rc));
|
||||||
|
rc = map_gcry_err (rc);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
if ( !gcry_pk_get_keygrip (s_pkey, grip) )
|
||||||
|
{
|
||||||
|
rc = seterr (General_Error);
|
||||||
|
log_error ("can't figure out the keygrip\n");
|
||||||
|
gcry_sexp_release (s_pkey);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
gcry_sexp_release (s_pkey);
|
||||||
|
for (n=0; n < 20; n++)
|
||||||
|
sprintf (hexgrip+n*2, "%02X", grip[n]);
|
||||||
|
|
||||||
|
rc = gpgsm_agent_pksign (hexgrip,
|
||||||
|
gcry_md_read(md, GCRY_MD_SHA1),
|
||||||
|
gcry_md_get_algo_dlen (GCRY_MD_SHA1),
|
||||||
|
GCRY_MD_SHA1,
|
||||||
|
&sigval, &siglen);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error ("signing failed: %s\n", gnupg_strerror (rc));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ksba_certreq_set_sig_val (cr, sigval);
|
||||||
|
xfree (sigval);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
log_error ("failed to store the sig_val: %s\n",
|
||||||
|
ksba_strerror (err));
|
||||||
|
rc = map_ksba_err (err);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (stopreason != KSBA_SR_READY);
|
||||||
|
|
||||||
|
|
||||||
|
leave:
|
||||||
|
gcry_md_close (md);
|
||||||
|
ksba_certreq_release (cr);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Create a new key by reading the parameters from in_fd. Multiple
|
||||||
|
keys may be created */
|
||||||
|
int
|
||||||
|
gpgsm_genkey (CTRL ctrl, int in_fd, FILE *out_fp)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
FILE *in_fp;
|
||||||
|
Base64Context b64writer = NULL;
|
||||||
|
KsbaWriter writer;
|
||||||
|
|
||||||
|
in_fp = fdopen (dup (in_fd), "rb");
|
||||||
|
if (!in_fp)
|
||||||
|
{
|
||||||
|
log_error ("fdopen() failed: %s\n", strerror (errno));
|
||||||
|
return seterr (IO_Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl->pem_name = "NEW CERTIFICATE REQUEST";
|
||||||
|
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error ("can't create writer: %s\n", gnupg_strerror (rc));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = read_parameters (in_fp, writer);
|
||||||
|
if (rc)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
rc = gpgsm_finish_writer (b64writer);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
log_error ("write failed: %s\n", gnupg_strerror (rc));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info ("certificate request created\n");
|
||||||
|
|
||||||
|
leave:
|
||||||
|
gpgsm_destroy_writer (b64writer);
|
||||||
|
fclose (in_fp);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
@ -447,6 +447,7 @@ gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
|
|||||||
}
|
}
|
||||||
encparm.fp = data_fp;
|
encparm.fp = data_fp;
|
||||||
|
|
||||||
|
ctrl->pem_name = "ENCRYPTED MESSAGE";
|
||||||
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
|
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
|
@ -187,3 +187,7 @@ gpgsm_get_keygrip_hexstring (KsbaCert cert)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,6 +98,7 @@ struct server_control_s {
|
|||||||
|
|
||||||
int create_base64; /* Create base64 encoded output */
|
int create_base64; /* Create base64 encoded output */
|
||||||
int create_pem; /* create PEM output */
|
int create_pem; /* create PEM output */
|
||||||
|
const char *pem_name; /* PEM name to use */
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef struct server_control_s *CTRL;
|
typedef struct server_control_s *CTRL;
|
||||||
@ -175,6 +176,9 @@ int gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int in_fd, FILE *out_fp);
|
|||||||
/*-- decrypt.c --*/
|
/*-- decrypt.c --*/
|
||||||
int gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp);
|
int gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp);
|
||||||
|
|
||||||
|
/*-- certreqgen.c --*/
|
||||||
|
int gpgsm_genkey (CTRL ctrl, int in_fd, FILE *out_fp);
|
||||||
|
|
||||||
/*-- call-agent.c --*/
|
/*-- call-agent.c --*/
|
||||||
int gpgsm_agent_pksign (const char *keygrip,
|
int gpgsm_agent_pksign (const char *keygrip,
|
||||||
unsigned char *digest,
|
unsigned char *digest,
|
||||||
@ -184,6 +188,7 @@ int gpgsm_agent_pksign (const char *keygrip,
|
|||||||
int gpgsm_agent_pkdecrypt (const char *keygrip,
|
int gpgsm_agent_pkdecrypt (const char *keygrip,
|
||||||
KsbaConstSexp ciphertext,
|
KsbaConstSexp ciphertext,
|
||||||
char **r_buf, size_t *r_buflen);
|
char **r_buf, size_t *r_buflen);
|
||||||
|
int gpgsm_agent_genkey (KsbaConstSexp keyparms, KsbaSexp *r_pubkey);
|
||||||
|
|
||||||
|
|
||||||
#endif /*GPGSM_H*/
|
#endif /*GPGSM_H*/
|
||||||
|
12
sm/keydb.c
12
sm/keydb.c
@ -35,8 +35,6 @@
|
|||||||
|
|
||||||
#define DIRSEP_C '/'
|
#define DIRSEP_C '/'
|
||||||
|
|
||||||
#define spacep(a) ((a) == ' ' || (a) == '\t')
|
|
||||||
|
|
||||||
static int active_handles;
|
static int active_handles;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -911,7 +909,7 @@ classify_user_id (const char *name,
|
|||||||
memset (desc, 0, sizeof *desc);
|
memset (desc, 0, sizeof *desc);
|
||||||
*force_exact = 0;
|
*force_exact = 0;
|
||||||
/* skip leading spaces. Fixme: what about trailing white space? */
|
/* skip leading spaces. Fixme: what about trailing white space? */
|
||||||
for(s = name; *s && spacep(*s); s++ )
|
for(s = name; *s && spacep (s); s++ )
|
||||||
;
|
;
|
||||||
|
|
||||||
switch (*s)
|
switch (*s)
|
||||||
@ -957,7 +955,7 @@ classify_user_id (const char *name,
|
|||||||
|
|
||||||
case '/': /* subject's DN */
|
case '/': /* subject's DN */
|
||||||
s++;
|
s++;
|
||||||
if (!*s || spacep (*s))
|
if (!*s || spacep (s))
|
||||||
return 0; /* no DN or prefixed with a space */
|
return 0; /* no DN or prefixed with a space */
|
||||||
desc->u.name = s;
|
desc->u.name = s;
|
||||||
mode = KEYDB_SEARCH_MODE_SUBJECT;
|
mode = KEYDB_SEARCH_MODE_SUBJECT;
|
||||||
@ -971,7 +969,7 @@ classify_user_id (const char *name,
|
|||||||
if ( *s == '/')
|
if ( *s == '/')
|
||||||
{ /* "#/" indicates an issuer's DN */
|
{ /* "#/" indicates an issuer's DN */
|
||||||
s++;
|
s++;
|
||||||
if (!*s || spacep (*s))
|
if (!*s || spacep (s))
|
||||||
return 0; /* no DN or prefixed with a space */
|
return 0; /* no DN or prefixed with a space */
|
||||||
desc->u.name = s;
|
desc->u.name = s;
|
||||||
mode = KEYDB_SEARCH_MODE_ISSUER;
|
mode = KEYDB_SEARCH_MODE_ISSUER;
|
||||||
@ -990,7 +988,7 @@ classify_user_id (const char *name,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
s = si+1;
|
s = si+1;
|
||||||
if (!*s || spacep (*s))
|
if (!*s || spacep (s))
|
||||||
return 0; /* no DN or prefixed with a space */
|
return 0; /* no DN or prefixed with a space */
|
||||||
desc->u.name = s;
|
desc->u.name = s;
|
||||||
mode = KEYDB_SEARCH_MODE_ISSUER_SN;
|
mode = KEYDB_SEARCH_MODE_ISSUER_SN;
|
||||||
@ -1038,7 +1036,7 @@ classify_user_id (const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if a hexadecimal number is terminated by EOS or blank */
|
/* check if a hexadecimal number is terminated by EOS or blank */
|
||||||
if (hexlength && s[hexlength] && !spacep(s[hexlength]))
|
if (hexlength && s[hexlength] && !spacep (s+hexlength))
|
||||||
{
|
{
|
||||||
if (hexprefix) /* a "0x" prefix without correct */
|
if (hexprefix) /* a "0x" prefix without correct */
|
||||||
return 0; /* termination is an error */
|
return 0; /* termination is an error */
|
||||||
|
90
sm/server.c
90
sm/server.c
@ -1,5 +1,5 @@
|
|||||||
/* server.c - Server mode and main entry point
|
/* server.c - Server mode and main entry point
|
||||||
* Copyright (C) 2001 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -42,45 +42,6 @@ struct server_local_s {
|
|||||||
CERTLIST recplist;
|
CERTLIST recplist;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Map GNUPG_xxx error codes to Assuan status codes */
|
|
||||||
static int
|
|
||||||
rc_to_assuan_status (int rc)
|
|
||||||
{
|
|
||||||
switch (rc)
|
|
||||||
{
|
|
||||||
case 0: break;
|
|
||||||
case GNUPG_Bad_Certificate: rc = ASSUAN_Bad_Certificate; break;
|
|
||||||
case GNUPG_Bad_Certificate_Path: rc = ASSUAN_Bad_Certificate_Path; break;
|
|
||||||
case GNUPG_Missing_Certificate: rc = ASSUAN_Missing_Certificate; break;
|
|
||||||
case GNUPG_No_Data: rc = ASSUAN_No_Data_Available; break;
|
|
||||||
case GNUPG_Bad_Signature: rc = ASSUAN_Bad_Signature; break;
|
|
||||||
case GNUPG_Not_Implemented: rc = ASSUAN_Not_Implemented; break;
|
|
||||||
case GNUPG_No_Agent: rc = ASSUAN_No_Agent; break;
|
|
||||||
case GNUPG_Agent_Error: rc = ASSUAN_Agent_Error; break;
|
|
||||||
case GNUPG_No_Public_Key: rc = ASSUAN_No_Public_Key; break;
|
|
||||||
case GNUPG_No_Secret_Key: rc = ASSUAN_No_Secret_Key; break;
|
|
||||||
case GNUPG_Invalid_Data: rc = ASSUAN_Invalid_Data; break;
|
|
||||||
case GNUPG_Invalid_Name: rc = ASSUAN_Invalid_Name; break;
|
|
||||||
|
|
||||||
case GNUPG_Read_Error:
|
|
||||||
case GNUPG_Write_Error:
|
|
||||||
case GNUPG_IO_Error:
|
|
||||||
rc = ASSUAN_Server_IO_Error;
|
|
||||||
break;
|
|
||||||
case GNUPG_Out_Of_Core:
|
|
||||||
case GNUPG_Resource_Limit:
|
|
||||||
rc = ASSUAN_Server_Resource_Problem;
|
|
||||||
break;
|
|
||||||
case GNUPG_Bug:
|
|
||||||
case GNUPG_Internal_Error:
|
|
||||||
rc = ASSUAN_Server_Bug;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
rc = ASSUAN_Server_Fault;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
close_message_fd (CTRL ctrl)
|
close_message_fd (CTRL ctrl)
|
||||||
@ -155,7 +116,7 @@ cmd_recipient (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
|
|
||||||
rc = gpgsm_add_to_certlist (line, &ctrl->server_local->recplist);
|
rc = gpgsm_add_to_certlist (line, &ctrl->server_local->recplist);
|
||||||
|
|
||||||
return rc_to_assuan_status (rc);
|
return map_to_assuan_status (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -204,7 +165,7 @@ cmd_encrypt (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
assuan_close_input_fd (ctx);
|
assuan_close_input_fd (ctx);
|
||||||
assuan_close_output_fd (ctx);
|
assuan_close_output_fd (ctx);
|
||||||
}
|
}
|
||||||
return rc_to_assuan_status (rc);
|
return map_to_assuan_status (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DECRYPT
|
/* DECRYPT
|
||||||
@ -243,7 +204,7 @@ cmd_decrypt (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
assuan_close_output_fd (ctx);
|
assuan_close_output_fd (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc_to_assuan_status (rc);
|
return map_to_assuan_status (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -288,7 +249,7 @@ cmd_verify (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
assuan_close_output_fd (ctx);
|
assuan_close_output_fd (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc_to_assuan_status (rc);
|
return map_to_assuan_status (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -329,7 +290,7 @@ cmd_sign (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
assuan_close_output_fd (ctx);
|
assuan_close_output_fd (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc_to_assuan_status (rc);
|
return map_to_assuan_status (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -358,7 +319,7 @@ cmd_import (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
assuan_close_input_fd (ctx);
|
assuan_close_input_fd (ctx);
|
||||||
assuan_close_output_fd (ctx);
|
assuan_close_output_fd (ctx);
|
||||||
}
|
}
|
||||||
return rc_to_assuan_status (rc);
|
return map_to_assuan_status (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MESSAGE FD=<n>
|
/* MESSAGE FD=<n>
|
||||||
@ -400,6 +361,42 @@ cmd_listkeys (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* GENKEY
|
||||||
|
|
||||||
|
Read the parameters in native format from the input fd and write a
|
||||||
|
certificate request to the output.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
cmd_genkey (ASSUAN_CONTEXT ctx, char *line)
|
||||||
|
{
|
||||||
|
CTRL ctrl = assuan_get_pointer (ctx);
|
||||||
|
int inp_fd, out_fd;
|
||||||
|
FILE *out_fp;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
inp_fd = assuan_get_input_fd (ctx);
|
||||||
|
if (inp_fd == -1)
|
||||||
|
return set_error (No_Input, NULL);
|
||||||
|
out_fd = assuan_get_output_fd (ctx);
|
||||||
|
if (out_fd == -1)
|
||||||
|
return set_error (No_Output, NULL);
|
||||||
|
|
||||||
|
out_fp = fdopen ( dup(out_fd), "w");
|
||||||
|
if (!out_fp)
|
||||||
|
return set_error (General_Error, "fdopen() failed");
|
||||||
|
rc = gpgsm_genkey (ctrl, inp_fd, out_fp);
|
||||||
|
fclose (out_fp);
|
||||||
|
|
||||||
|
if (!rc)
|
||||||
|
{
|
||||||
|
/* close and reset the fds */
|
||||||
|
assuan_close_input_fd (ctx);
|
||||||
|
assuan_close_output_fd (ctx);
|
||||||
|
}
|
||||||
|
return map_to_assuan_status (rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -423,6 +420,7 @@ register_commands (ASSUAN_CONTEXT ctx)
|
|||||||
{ "", ASSUAN_CMD_OUTPUT, NULL },
|
{ "", ASSUAN_CMD_OUTPUT, NULL },
|
||||||
{ "MESSAGE", 0, cmd_message },
|
{ "MESSAGE", 0, cmd_message },
|
||||||
{ "LISTKEYS", 0, cmd_listkeys },
|
{ "LISTKEYS", 0, cmd_listkeys },
|
||||||
|
{ "GENKEY", 0, cmd_genkey },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
int i, j, rc;
|
int i, j, rc;
|
||||||
|
@ -142,6 +142,7 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctrl->pem_name = "SIGNED MESSAGE";
|
||||||
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
|
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user