Implemented encryption in server mode.

Allow to specify a recipient on the commandline
There is still a default hardwired recipient if none has been set.
This commit is contained in:
Werner Koch 2001-12-11 12:31:04 +00:00
parent f463880562
commit 6a8c47bd29
11 changed files with 485 additions and 59 deletions

View File

@ -32,6 +32,7 @@ gpgsm_SOURCES = \
call-agent.c \
fingerprint.c \
base64.c \
certlist.c \
certdump.c \
certcheck.c \
certpath.c \

88
sm/certlist.c Normal file
View File

@ -0,0 +1,88 @@
/* certlist.c - build list of certificates
* Copyright (C) 2001 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
*/
#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"
int
gpgsm_add_to_certlist (const char *name, CERTLIST *listaddr)
{
int rc;
KEYDB_SEARCH_DESC desc;
KEYDB_HANDLE kh = NULL;
KsbaCert cert = NULL;
/* fixme: check that we identify excactly one cert with the name */
rc = keydb_classify_name (name, &desc);
if (!rc)
{
kh = keydb_new (0);
if (!kh)
rc = GNUPG_Out_Of_Core;
else
{
rc = keydb_search (kh, &desc, 1);
if (!rc)
rc = keydb_get_cert (kh, &cert);
if (!rc)
{
CERTLIST cl = xtrycalloc (1, sizeof *cl);
if (!cl)
rc = GNUPG_Out_Of_Core;
else
{
cl->cert = cert; cert = NULL;
cl->next = *listaddr;
*listaddr = cl;
}
}
}
}
keydb_release (kh);
ksba_cert_release (cert);
return rc;
}
void
gpgsm_release_certlist (CERTLIST list)
{
while (list)
{
CERTLIST cl = list->next;
ksba_cert_release (list->cert);
xfree (list);
list = cl;
}
}

View File

@ -36,6 +36,7 @@
struct decrypt_filter_parm_s {
int algo;
int mode;
int blklen;
GCRY_CIPHER_HD hd;
char iv[16];
@ -110,7 +111,7 @@ prepare_decryption (const char *hexkeygrip, const char *enc_val,
if (DBG_CRYPTO)
log_printhex ("session key:", seskey+n, seskeylen-n);
parm->hd = gcry_cipher_open (parm->algo, GCRY_CIPHER_MODE_CBC, 0);
parm->hd = gcry_cipher_open (parm->algo, parm->mode, 0);
if (!parm->hd)
{
rc = gcry_errno ();
@ -311,23 +312,24 @@ gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp)
rc = map_ksba_err (err);
goto leave;
}
log_debug ("ksba_cms_parse - stop reason %d\n", stopreason);
if (stopreason == KSBA_SR_BEGIN_DATA
|| stopreason == KSBA_SR_DETACHED_DATA)
{
int algo;
int algo, mode;
const char *algoid;
algoid = ksba_cms_get_content_oid (cms, 2/* encryption algo*/);
algo = gcry_cipher_map_name (algoid);
if (!algo)
mode = gcry_cipher_mode_from_oid (algoid);
if (!algo || !mode)
{
log_error ("unsupported algorithm `%s'\n", algoid? algoid:"?");
rc = GNUPG_Unsupported_Algorithm;
goto leave;
}
dfparm.algo = algo;
dfparm.mode = mode;
dfparm.blklen = gcry_cipher_get_algo_blklen (algo);
if (dfparm.blklen > sizeof (dfparm.helpblock))
return GNUPG_Bug;

View File

@ -62,17 +62,25 @@ static KsbaCert
get_default_recipient (void)
{
const char key[] =
"CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=#44FC7373656C646F7266#,C=DE";
"/CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=#44FC7373656C646F7266#,C=DE";
KEYDB_SEARCH_DESC desc;
KsbaCert cert = NULL;
KEYDB_HANDLE kh = NULL;
int rc;
rc = keydb_classify_name (key, &desc);
if (rc)
{
log_error ("failed to find recipient: %s\n", gnupg_strerror (rc));
return NULL;
}
kh = keydb_new (0);
if (!kh)
return NULL;
rc = keydb_search_subject (kh, key);
rc = keydb_search (kh, &desc, 1);
if (rc)
{
log_debug ("failed to find default certificate: rc=%d\n", rc);
@ -96,10 +104,11 @@ get_default_recipient (void)
static int
init_dek (DEK dek)
{
int rc=0, i;
int rc=0, mode, i;
dek->algo = gcry_cipher_map_name (dek->algoid);
if (!dek->algo)
mode = gcry_cipher_mode_from_oid (dek->algoid);
if (!dek->algo || !mode)
{
log_error ("unsupported algorithm `%s'\n", dek->algoid);
return GNUPG_Unsupported_Algorithm;
@ -119,10 +128,7 @@ init_dek (DEK dek)
return GNUPG_Unsupported_Algorithm;
}
dek->chd = gcry_cipher_open (dek->algo,
GCRY_CIPHER_MODE_CBC,
GCRY_CIPHER_SECURE);
dek->chd = gcry_cipher_open (dek->algo, mode, GCRY_CIPHER_SECURE);
if (!dek->chd)
{
log_error ("failed to create cipher context: %s\n", gcry_strerror (-1));
@ -369,9 +375,10 @@ encrypt_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
/* Perform an encrypt operation.
Encrypt the data received on DATA-FD and write it to OUT_FP. The
recipients are hardwired for now. */
recipients are take from the certificate given in recplist; if this
is NULL it will be encrypted for a default recipient */
int
gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int data_fd, FILE *out_fp)
{
int rc = 0;
Base64Context b64writer = NULL;
@ -385,9 +392,12 @@ gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
DEK dek = NULL;
int recpno;
FILE *data_fp = NULL;
struct certlist_s help_recplist;
CERTLIST cl;
memset (&encparm, 0, sizeof encparm);
help_recplist.next = NULL;
help_recplist.cert = NULL;
kh = keydb_new (0);
if (!kh)
{
@ -396,6 +406,19 @@ gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
goto leave;
}
/* If no recipient list is given, use a default one */
if (!recplist)
{
help_recplist.cert = get_default_recipient ();
if (!help_recplist.cert)
{
log_error ("no default recipient found\n");
rc = seterr (General_Error);
goto leave;
}
recplist = &help_recplist;
}
data_fp = fdopen ( dup (data_fd), "rb");
if (!data_fp)
{
@ -458,7 +481,7 @@ gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
rc = GNUPG_Out_Of_Core;
else
{
dek->algoid = "1.2.840.113549.3.7"; /*des-EDE3-CBC*/
dek->algoid = opt.def_cipher_algoid;
rc = init_dek (dek);
}
if (rc)
@ -490,40 +513,27 @@ gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
/* gather certificates of recipients, encrypt the session key for
each and store them in the CMS object */
for (recpno = 0; recpno < 1; recpno++)
for (recpno = 0, cl = recplist; cl; recpno++, cl = cl->next)
{
KsbaCert cert;
char *encval;
/* fixme: get the recipients out of the arguments passed to us */
cert = get_default_recipient ();
if (!cert)
{
log_error ("no default recipient found\n");
rc = seterr (General_Error);
goto leave;
}
rc = encrypt_dek (dek, cert, &encval);
rc = encrypt_dek (dek, cl->cert, &encval);
if (rc)
{
log_error ("encryption failed for recipient no. %d: %s\n",
recpno, gnupg_strerror (rc));
ksba_cert_release (cert);
goto leave;
}
err = ksba_cms_add_recipient (cms, cert);
err = ksba_cms_add_recipient (cms, cl->cert);
if (err)
{
log_error ("ksba_cms_add_recipient failed: %s\n",
ksba_strerror (err));
rc = map_ksba_err (err);
xfree (encval);
ksba_cert_release (cert);
goto leave;
}
cert = NULL; /* cms does now own the certificate */
err = ksba_cms_set_enc_val (cms, recpno, encval);
xfree (encval);
@ -547,7 +557,6 @@ gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
rc = map_ksba_err (err);
goto leave;
}
log_debug ("ksba_cms_build - stop reason %d\n", stopreason);
}
while (stopreason != KSBA_SR_READY);
@ -576,5 +585,7 @@ gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
if (data_fp)
fclose (data_fp);
xfree (encparm.buffer);
if (help_recplist.cert)
ksba_cert_release (help_recplist.cert);
return rc;
}

View File

@ -512,10 +512,10 @@ main ( int argc, char **argv)
int nogreeting = 0;
int use_random_seed = 1;
int with_fpr = 0;
char *def_cipher_string = NULL;
char *def_digest_string = NULL;
enum cmd_and_opt_values cmd = 0;
struct server_control_s ctrl;
CERTLIST recplist = NULL;
/* FIXME: trap_unaligned ();*/
set_strusage (my_strusage);
@ -541,6 +541,7 @@ main ( int argc, char **argv)
create_dotlock (NULL); /* register locking cleanup */
i18n_init();
opt.def_cipher_algoid = "1.2.840.113549.3.7"; /*des-EDE3-CBC*/
#ifdef __MINGW32__
opt.homedir = read_w32_registry_string ( NULL,
"Software\\GNU\\GnuPG", "HomeDir" );
@ -762,6 +763,10 @@ main ( int argc, char **argv)
gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);
break;
case oCipherAlgo:
opt.def_cipher_algoid = pargs.r.ret_str;
break;
case oDisableCipherAlgo:
{
int algo = gcry_cipher_map_name (pargs.r.ret_str);
@ -780,6 +785,8 @@ main ( int argc, char **argv)
case oEnableSpecialFilenames: allow_special_filenames =1; break;
default:
pargs.err = configfp? 1:2;
break;
@ -832,16 +839,12 @@ main ( int argc, char **argv)
/* FIXME: should set filenames of libgcrypt explicitly
* gpg_opt_homedir = opt.homedir; */
/* must do this after dropping setuid, because string_to...
* may try to load an module */
if (def_cipher_string)
{
opt.def_cipher_algo = gcry_cipher_map_name (def_cipher_string);
xfree (def_cipher_string);
def_cipher_string = NULL;
if ( our_cipher_test_algo (opt.def_cipher_algo) )
log_error (_("selected cipher algorithm is invalid\n"));
}
/* must do this after dropping setuid, because the mapping functions
may try to load an module and we may have disabled an algorithm */
if ( !gcry_cipher_map_name (opt.def_cipher_algoid)
|| !gcry_cipher_mode_from_oid (opt.def_cipher_algoid))
log_error (_("selected cipher algorithm is invalid\n"));
if (def_digest_string)
{
opt.def_digest_algo = gcry_md_map_name (def_digest_string);
@ -875,6 +878,18 @@ main ( int argc, char **argv)
for (sl = nrings; sl; sl = sl->next)
keydb_add_resource (sl->d, 0, 0);
FREE_STRLIST(nrings);
for (sl = remusr; sl; sl = sl->next)
{
int rc = gpgsm_add_to_certlist (sl->d, &recplist);
if (rc)
log_error (_("can't encrypt to `%s': %s\n"),
sl->d, gnupg_strerror (rc));
}
if (log_get_errorcount(0))
gpgsm_exit(1); /* must stop for invalid recipients */
fname = argc? *argv : NULL;
@ -886,9 +901,9 @@ main ( int argc, char **argv)
case aEncr: /* encrypt the given file */
if (!argc)
gpgsm_encrypt (&ctrl, 0, stdout); /* from stdin */
gpgsm_encrypt (&ctrl, recplist, 0, stdout); /* from stdin */
else if (argc == 1)
gpgsm_encrypt (&ctrl, open_read (*argv), stdout); /* from file */
gpgsm_encrypt (&ctrl, recplist, open_read (*argv), stdout); /* from file */
else
wrong_args (_("--encrypt [datafile]"));
break;
@ -1066,6 +1081,7 @@ main ( int argc, char **argv)
}
/* cleanup */
gpgsm_release_certlist (recplist);
FREE_STRLIST(remusr);
FREE_STRLIST(locusr);
gpgsm_exit(0);

View File

@ -48,7 +48,9 @@ struct {
int armor; /* force base64 armoring (see also ctrl.with_base64) */
int no_armor; /* don't try to figure out whether data is base64 armored*/
int def_cipher_algo; /* cipher algorithm to use if nothing else is know */
const char *def_cipher_algoid; /* cipher algorithm to use if
nothing else is specified */
int def_digest_algo; /* Ditto for hash algorithm */
int def_compress_algo; /* Ditto for compress algorithm */
@ -100,10 +102,16 @@ struct server_control_s {
};
typedef struct server_control_s *CTRL;
/* data structure osed in base64.c */
/* data structure used in base64.c */
typedef struct base64_context_s *Base64Context;
struct certlist_s {
struct certlist_s *next;
KsbaCert cert;
};
typedef struct certlist_s *CERTLIST;
/*-- gpgsm.c --*/
void gpgsm_exit (int rc);
@ -143,6 +151,10 @@ int gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo,
/*-- certpath.c --*/
int gpgsm_validate_path (KsbaCert cert);
/*-- cetlist.c --*/
int gpgsm_add_to_certlist (const char *name, CERTLIST *listaddr);
void gpgsm_release_certlist (CERTLIST list);
/*-- keylist.c --*/
void gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp);
@ -156,7 +168,7 @@ int gpgsm_verify (CTRL ctrl, int in_fd, int data_fd);
int gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp);
/*-- encrypt.c --*/
int gpgsm_encrypt (CTRL ctrl, int in_fd, FILE *out_fp);
int gpgsm_encrypt (CTRL ctrl, CERTLIST recplist, int in_fd, FILE *out_fp);
/*-- decrypt.c --*/
int gpgsm_decrypt (CTRL ctrl, int in_fd, FILE *out_fp);
@ -174,3 +186,5 @@ int gpgsm_agent_pkdecrypt (const char *keygrip,
#endif /*GPGSM_H*/

View File

@ -35,6 +35,8 @@
#define DIRSEP_C '/'
#define spacep(a) ((a) == ' ' || (a) == '\t')
static int active_handles;
typedef enum {
@ -859,4 +861,277 @@ keydb_search_subject (KEYDB_HANDLE hd, const char *name)
}
static int
hextobyte (const unsigned char *s)
{
int c;
if( *s >= '0' && *s <= '9' )
c = 16 * (*s - '0');
else if ( *s >= 'A' && *s <= 'F' )
c = 16 * (10 + *s - 'A');
else if ( *s >= 'a' && *s <= 'f' )
c = 16 * (10 + *s - 'a');
else
return -1;
s++;
if ( *s >= '0' && *s <= '9' )
c += *s - '0';
else if ( *s >= 'A' && *s <= 'F' )
c += 10 + *s - 'A';
else if ( *s >= 'a' && *s <= 'f' )
c += 10 + *s - 'a';
else
return -1;
return c;
}
static int
classify_user_id (const char *name,
KEYDB_SEARCH_DESC *desc,
int *force_exact )
{
const char *s;
int hexprefix = 0;
int hexlength;
int mode = 0;
/* clear the structure so that the mode field is set to zero unless
* we set it to the correct value right at the end of this function */
memset (desc, 0, sizeof *desc);
*force_exact = 0;
/* skip leading spaces. Fixme: what about trailing white space? */
for(s = name; *s && spacep(*s); s++ )
;
switch (*s)
{
case 0: /* empty string is an error */
return 0;
case '.': /* an email address, compare from end */
mode = KEYDB_SEARCH_MODE_MAILEND;
s++;
desc->u.name = s;
break;
case '<': /* an email address */
mode = KEYDB_SEARCH_MODE_MAIL;
desc->u.name = s;
break;
case '@': /* part of an email address */
mode = KEYDB_SEARCH_MODE_MAILSUB;
s++;
desc->u.name = s;
break;
case '=': /* exact compare */
mode = KEYDB_SEARCH_MODE_EXACT;
s++;
desc->u.name = s;
break;
case '*': /* case insensitive substring search */
mode = KEYDB_SEARCH_MODE_SUBSTR;
s++;
desc->u.name = s;
break;
case '+': /* compare individual words */
mode = KEYDB_SEARCH_MODE_WORDS;
s++;
desc->u.name = s;
break;
case '/': /* subject's DN */
s++;
if (!*s || spacep (*s))
return 0; /* no DN or prefixed with a space */
desc->u.name = s;
mode = KEYDB_SEARCH_MODE_SUBJECT;
break;
case '#':
{
const char *si;
s++;
if ( *s == '/')
{ /* "#/" indicates an issuer's DN */
s++;
if (!*s || spacep (*s))
return 0; /* no DN or prefixed with a space */
desc->u.name = s;
mode = KEYDB_SEARCH_MODE_ISSUER;
}
else
{ /* serialnumber + optional issuer ID */
for (si=s; *si && *si != '/'; si++)
{
if (!strchr("01234567890abcdefABCDEF", *si))
return 0; /* invalid digit in serial number*/
}
desc->sn = s;
desc->sn_is_string = 1;
if (!*si)
mode = KEYDB_SEARCH_MODE_SN;
else
{
s = si+1;
if (!*s || spacep (*s))
return 0; /* no DN or prefixed with a space */
desc->u.name = s;
mode = KEYDB_SEARCH_MODE_ISSUER_SN;
}
}
}
break;
case ':': /*Unified fingerprint */
{
const char *se, *si;
int i;
se = strchr (++s,':');
if (!se)
return 0;
for (i=0,si=s; si < se; si++, i++ )
{
if (!strchr("01234567890abcdefABCDEF", *si))
return 0; /* invalid digit */
}
if (i != 32 && i != 40)
return 0; /* invalid length of fpr*/
for (i=0,si=s; si < se; i++, si +=2)
desc->u.fpr[i] = hextobyte(si);
for (; i < 20; i++)
desc->u.fpr[i]= 0;
s = se + 1;
mode = KEYDB_SEARCH_MODE_FPR;
}
break;
default:
if (s[0] == '0' && s[1] == 'x')
{
hexprefix = 1;
s += 2;
}
hexlength = strspn(s, "0123456789abcdefABCDEF");
if (hexlength >= 8 && s[hexlength] =='!')
{
*force_exact = 1;
hexlength++; /* just for the following check */
}
/* check if a hexadecimal number is terminated by EOS or blank */
if (hexlength && s[hexlength] && !spacep(s[hexlength]))
{
if (hexprefix) /* a "0x" prefix without correct */
return 0; /* termination is an error */
/* The first chars looked like a hex number, but really is
not */
hexlength = 0;
}
if (*force_exact)
hexlength--; /* remove the bang */
if (hexlength == 8
|| (!hexprefix && hexlength == 9 && *s == '0'))
{ /* short keyid */
unsigned long kid;
if (hexlength == 9)
s++;
kid = strtoul( s, NULL, 16 );
desc->u.kid[4] = kid >> 24;
desc->u.kid[5] = kid >> 16;
desc->u.kid[6] = kid >> 8;
desc->u.kid[7] = kid;
mode = KEYDB_SEARCH_MODE_SHORT_KID;
}
else if (hexlength == 16
|| (!hexprefix && hexlength == 17 && *s == '0'))
{ /* complete keyid */
unsigned long kid0, kid1;
char buf[9];
if (hexlength == 17)
s++;
mem2str(buf, s, 9 );
kid0 = strtoul (buf, NULL, 16);
kid1 = strtoul (s+8, NULL, 16);
desc->u.kid[0] = kid0 >> 24;
desc->u.kid[1] = kid0 >> 16;
desc->u.kid[2] = kid0 >> 8;
desc->u.kid[3] = kid0;
desc->u.kid[4] = kid1 >> 24;
desc->u.kid[5] = kid1 >> 16;
desc->u.kid[6] = kid1 >> 8;
desc->u.kid[7] = kid1;
mode = KEYDB_SEARCH_MODE_LONG_KID;
}
else if (hexlength == 32
|| (!hexprefix && hexlength == 33 && *s == '0'))
{ /* md5 fingerprint */
int i;
if (hexlength == 33)
s++;
memset(desc->u.fpr+16, 0, 4);
for (i=0; i < 16; i++, s+=2)
{
int c = hextobyte(s);
if (c == -1)
return 0;
desc->u.fpr[i] = c;
}
mode = KEYDB_SEARCH_MODE_FPR16;
}
else if (hexlength == 40
|| (!hexprefix && hexlength == 41 && *s == '0'))
{ /* sha1/rmd160 fingerprint */
int i;
if (hexlength == 41)
s++;
for (i=0; i < 20; i++, s+=2)
{
int c = hextobyte(s);
if (c == -1)
return 0;
desc->u.fpr[i] = c;
}
mode = KEYDB_SEARCH_MODE_FPR20;
}
else if (!hexprefix)
{ /* default is substring search */
*force_exact = 0;
desc->u.name = s;
mode = KEYDB_SEARCH_MODE_SUBSTR;
}
else
{ /* hex number with a prefix but a wrong length */
return 0;
}
}
desc->mode = mode;
return mode;
}
int
keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc)
{
int dummy;
KEYDB_SEARCH_DESC dummy_desc;
if (!desc)
desc = &dummy_desc;
if (!classify_user_id (name, desc, &dummy))
return GNUPG_Invalid_Name;
return 0;
}

View File

@ -60,6 +60,8 @@ int keydb_search_issuer_sn (KEYDB_HANDLE hd,
const char *issuer, const unsigned char *serial);
int keydb_search_subject (KEYDB_HANDLE hd, const char *issuer);
int keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc);
#endif /*GNUPG_KEYDB_H*/

View File

@ -40,6 +40,7 @@ static FILE *statusfp;
struct server_local_s {
ASSUAN_CONTEXT assuan_ctx;
int message_fd;
CERTLIST recplist;
};
/* Map GNUPG_xxx error codes to Assuan status codes */
@ -60,6 +61,7 @@ rc_to_assuan_status (int rc)
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:
@ -81,10 +83,13 @@ rc_to_assuan_status (int rc)
return rc;
}
static void
reset_notify (ASSUAN_CONTEXT ctx)
{
CTRL ctrl = assuan_get_pointer (ctx);
gpgsm_release_certlist (ctrl->server_local->recplist);
ctrl->server_local->recplist = NULL;
}
@ -131,13 +136,16 @@ output_notify (ASSUAN_CONTEXT ctx, const char *line)
the encryption will then not be done for this recipient. IF the
policy is not to encrypt at all if not all recipients are valid, the
client has to take care of this. All RECIPIENT commands are
cumulative until a RESET or ENCRYPT command. */
cumulative until a RESET or an successful ENCRYPT command. */
static int
cmd_recipient (ASSUAN_CONTEXT ctx, char *line)
{
CTRL ctrl = assuan_get_pointer (ctx);
int rc;
return set_error (Not_Implemented, "fixme");
rc = gpgsm_add_to_certlist (line, &ctrl->server_local->recplist);
return rc_to_assuan_status (rc);
}
@ -157,6 +165,7 @@ cmd_recipient (ASSUAN_CONTEXT ctx, char *line)
static int
cmd_encrypt (ASSUAN_CONTEXT ctx, char *line)
{
CTRL ctrl = assuan_get_pointer (ctx);
int inp_fd, out_fd;
FILE *out_fp;
int rc;
@ -171,9 +180,16 @@ cmd_encrypt (ASSUAN_CONTEXT ctx, char *line)
out_fp = fdopen ( dup(out_fd), "w");
if (!out_fp)
return set_error (General_Error, "fdopen() failed");
rc = gpgsm_encrypt (assuan_get_pointer (ctx), inp_fd, out_fp);
rc = gpgsm_encrypt (assuan_get_pointer (ctx),
ctrl->server_local->recplist,
inp_fd, out_fp);
fclose (out_fp);
if (!rc)
{
gpgsm_release_certlist (ctrl->server_local->recplist);
ctrl->server_local->recplist = NULL;
}
return rc_to_assuan_status (rc);
}
@ -181,9 +197,9 @@ cmd_encrypt (ASSUAN_CONTEXT ctx, char *line)
This performs the decrypt operation after doing some check on the
internal state. (e.g. that only needed data has been set). Because
it utilises the GPG-Agent for the session key decryption, there is
it utilizes the GPG-Agent for the session key decryption, there is
no need to ask the client for a protecting passphrase - GpgAgent
does take care of this but requesting this from the user. */
does take care of this by requesting this from the user. */
static int
cmd_decrypt (ASSUAN_CONTEXT ctx, char *line)
{
@ -412,6 +428,8 @@ gpgsm_server (void)
}
}
gpgsm_release_certlist (ctrl.server_local->recplist);
ctrl.server_local->recplist = NULL;
assuan_deinit_pipe_server (ctx);
}

View File

@ -186,7 +186,7 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
rc = map_ksba_err (err);
goto leave;
}
cert = NULL; /* cms does now own the certificate */
ksba_cert_release (cert); cert = NULL;
/* fixme: We might want to include a list of certificate which are
put as info into the signed data object - maybe we should add a
@ -270,7 +270,6 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
rc = map_ksba_err (err);
goto leave;
}
log_debug ("ksba_cms_build - stop reason %d\n", stopreason);
if (stopreason == KSBA_SR_BEGIN_DATA)
{ /* hash the data and store the message digest */

View File

@ -227,7 +227,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
rc = map_ksba_err (err);
goto leave;
}
log_debug ("ksba_cms_parse - stop reason %d\n", stopreason);
if (stopreason == KSBA_SR_NEED_HASH)
{
is_detached = 1;