* base64.c: New. Changed all other functions to use this instead

of direct creation of ksba_reader/writer.
* gpgsm.c (main): Set ctrl.auto_encoding unless --no-armor is used.
This way we can feed PEM encoded stuff to --verify.
This commit is contained in:
Werner Koch 2001-11-27 17:40:09 +00:00
parent 5a6a2ca248
commit 944fee70bc
10 changed files with 782 additions and 331 deletions

View File

@ -1,3 +1,9 @@
2001-11-27 Werner Koch <wk@gnupg.org>
* base64.c: New. Changed all other functions to use this instead
of direct creation of ksba_reader/writer.
* gpgsm.c (main): Set ctrl.auto_encoding unless --no-armor is used.
2001-11-26 Werner Koch <wk@gnupg.org>
* gpgsm.c: New option --agent-program

View File

@ -31,12 +31,14 @@ gpgsm_SOURCES = \
server.c \
call-agent.c \
fingerprint.c \
base64.c \
certdump.c \
certcheck.c \
certpath.c \
keylist.c \
verify.c \
sign.c \
encrypt.c \
import.c

401
sm/base64.c Normal file
View File

@ -0,0 +1,401 @@
/* base64.c
* 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 <ksba.h>
#include "gpgsm.h"
#include "i18n.h"
/* data used by the reader callbacks */
struct reader_cb_parm_s {
FILE *fp;
unsigned char line[1024];
int linelen;
int readpos;
int have_lf;
unsigned long line_counter;
int autodetect; /* try to detect the input encoding */
int assume_pem; /* assume input encoding is PEM */
int assume_base64; /* assume inpout is base64 encoded */
int identified;
int is_pem;
int stop_seen;
struct {
int idx;
unsigned char val;
int stop_seen;
} base64;
};
struct base64_context_s {
struct reader_cb_parm_s rparm;
};
/* The base-64 character list */
static unsigned char bintoasc[64] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
/* The reverse base-64 list */
static unsigned char asctobin[256] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff
};
static int
base64_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
{
struct reader_cb_parm_s *parm = cb_value;
size_t n;
int c, c2;
*nread = 0;
if (!buffer)
return -1; /* not supported */
next:
if (!parm->linelen)
{
/* read an entire line or up to the size of the buffer */
parm->line_counter++;
parm->have_lf = 0;
for (n=0; n < DIM(parm->line);)
{
c = getc (parm->fp);
if (c == EOF)
{
if (ferror (parm->fp))
return -1;
break;
}
parm->line[n++] = c;
if (c == '\n')
{
parm->have_lf = 1;
/* FIXME: we need to skip overlong lines while detecting
the dashed lines */
break;
}
}
parm->linelen = n;
if (!n)
return -1; /* eof */
parm->readpos = 0;
}
if (!parm->identified)
{
if (parm->line_counter == 1 && !parm->have_lf)
{
/* first line too long - assume DER encoding */
parm->is_pem = 0;
}
else if (parm->line_counter == 1 && parm->linelen && *parm->line == 0x30)
{
/* the very first bytes does pretty much look like a SEQUENCE tag*/
parm->is_pem = 0;
}
else if ( parm->have_lf && !strncmp (parm->line, "-----BEGIN ", 11)
&& strncmp (parm->line+11, "PGP ", 4) )
{
/* Fixme: we must only compare if the line really starts at
the beginning */
parm->is_pem = 1;
parm->linelen = parm->readpos = 0;
}
else
{
parm->linelen = parm->readpos = 0;
goto next;
}
parm->identified = 1;
parm->base64.stop_seen = 0;
parm->base64.idx = 0;
}
n = 0;
if (parm->is_pem)
{
if (parm->have_lf && !strncmp (parm->line, "-----END ", 9))
{
parm->identified = 0;
parm->linelen = parm->readpos = 0;
/* let us return 0 */
}
else if (parm->stop_seen)
{ /* skip the rest of the line */
parm->linelen = parm->readpos = 0;
}
else
{
int idx = parm->base64.idx;
unsigned char val = parm->base64.val;
while (n < count && parm->readpos < parm->linelen )
{
c = parm->line[parm->readpos++];
if (c == '\n' || c == ' ' || c == '\r' || c == '\t')
continue;
if (c == '=')
{ /* pad character: stop */
if (idx == 1)
buffer[n++] = val;
parm->stop_seen = 1;
break;
}
if( (c = asctobin[(c2=c)]) == 255 )
{
log_error (_("invalid radix64 character %02x skipped\n"),
c2);
continue;
}
switch (idx)
{
case 0:
val = c << 2;
break;
case 1:
val |= (c>>4)&3;
buffer[n++] = val;
val = (c<<4)&0xf0;
break;
case 2:
val |= (c>>2)&15;
buffer[n++] = val;
val = (c<<6)&0xc0;
break;
case 3:
val |= c&0x3f;
buffer[n++] = val;
break;
}
idx = (idx+1) % 4;
}
if (parm->readpos == parm->linelen)
parm->linelen = parm->readpos = 0;
parm->base64.idx = idx;
parm->base64.val = val;
}
}
else
{ /* DER encoded */
while (n < count && parm->readpos < parm->linelen)
buffer[n++] = parm->line[parm->readpos++];
if (parm->readpos == parm->linelen)
parm->linelen = parm->readpos = 0;
}
*nread = n;
return 0;
}
static int
simple_reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
{
struct reader_cb_parm_s *parm = cb_value;
size_t n;
int c = 0;
*nread = 0;
if (!buffer)
return -1; /* not supported */
for (n=0; n < count; n++)
{
c = getc (parm->fp);
if (c == EOF)
{
if ( ferror (parm->fp) )
return -1;
if (n)
break; /* return what we have before an EOF */
return -1;
}
*(byte *)buffer++ = c;
}
*nread = n;
return 0;
}
/* Create a reader for the given file descriptor. Depending on the
control information an input decoding is automagically choosen.
The function returns a Base64Context object which must be passed to
the gpgme_destroy_reader function. The created KsbaReader object
is also returned, but the caller must not call the
ksba_reader_release function on. */
int
gpgsm_create_reader (Base64Context *ctx,
CTRL ctrl, FILE *fp, KsbaReader *r_reader)
{
int rc;
KsbaReader r;
*r_reader = NULL;
*ctx = xtrycalloc (1, sizeof **ctx);
if (!*ctx)
return seterr (Out_Of_Core);
r = ksba_reader_new ();
if (!r)
{
xfree (*ctx); *ctx = NULL;
return seterr (Out_Of_Core);
}
(*ctx)->rparm.fp = fp;
if (ctrl->is_pem)
{
(*ctx)->rparm.assume_pem = 1;
(*ctx)->rparm.assume_base64 = 1;
rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->rparm);
}
else if (ctrl->is_base64)
{
(*ctx)->rparm.assume_base64 = 1;
rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->rparm);
}
else if (ctrl->autodetect_encoding)
{
(*ctx)->rparm.autodetect = 1;
rc = ksba_reader_set_cb (r, base64_reader_cb, &(*ctx)->rparm);
}
else
rc = ksba_reader_set_cb (r, simple_reader_cb, &(*ctx)->rparm);
if (rc)
{
ksba_reader_release (r);
xfree (*ctx); *ctx = NULL;
return map_ksba_err (rc);
}
*r_reader = r;
return 0;
}
void
gpgsm_destroy_reader (Base64Context ctx)
{
xfree (ctx);
}
/* Create a writer for the given stream. Depending on the control
information an output encoding is automagically choosen. The
function returns a Base64Context object which must be passed to the
gpgme_destroy_writer function. The created KsbaWriter object is
also returned, but the caller must not call the ksba_reader_release
function on. */
int
gpgsm_create_writer (Base64Context *ctx,
CTRL ctrl, FILE *fp, KsbaWriter *r_writer)
{
int rc;
KsbaWriter w;
*r_writer = NULL;
*ctx = xtrycalloc (1, sizeof **ctx);
if (!*ctx)
return seterr (Out_Of_Core);
w = ksba_writer_new ();
if (!w)
{
xfree (*ctx); *ctx = NULL;
return seterr (Out_Of_Core);
}
if (ctrl->create_pem || ctrl->create_base64)
{
return seterr (Not_Implemented);
}
else
rc = ksba_writer_set_file (w, fp);
if (rc)
{
ksba_writer_release (w);
xfree (*ctx); *ctx = NULL;
return map_ksba_err (rc);
}
*r_writer = w;
return 0;
}
void
gpgsm_destroy_writer (Base64Context ctx)
{
xfree (ctx);
}

256
sm/encrypt.c Normal file
View File

@ -0,0 +1,256 @@
/* encrypt.c - Encrypt a message
* 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"
#include "i18n.h"
KsbaCert
get_default_recipient (void)
{
return NULL;
}
/* Perform an encrypt operation.
Encrypt the data received on DATA-FD and write it to OUT_FP. The
recipients are hardwired for now. */
int
gpgsm_encrypt (CTRL ctrl, int data_fd, FILE *out_fp)
{
int i, rc;
Base64Context b64reader = NULL;
Base64Context b64writer = NULL;
KsbaError err;
KsbaWriter writer;
KsbaReader reader;
KsbaCMS cms = NULL;
KsbaStopReason stopreason;
KsbaCert cert;
KEYDB_HANDLE kh = NULL;
GCRY_MD_HD data_md = NULL;
int signer;
const char *algoid;
FILE *data_fp = NULL;
int algo;
kh = keydb_new (0);
if (!kh)
{
log_error (_("failed to allocated keyDB handle\n"));
rc = GNUPG_General_Error;
goto leave;
}
data_fp = fdopen ( dup (data_fd), "rb");
if (!data_fp)
{
log_error ("fdopen() failed: %s\n", strerror (errno));
rc = seterr (IO_Error);
goto leave;
}
rc = gpgsm_create_reader (&b64reader, ctrl, data_fp, &reader);
if (rc)
{
log_error ("can't create reader: %s\n", gnupg_strerror (rc));
goto leave;
}
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
if (rc)
{
log_error ("can't create writer: %s\n", gnupg_strerror (rc));
goto leave;
}
cms = ksba_cms_new ();
if (!cms)
{
rc = seterr (Out_Of_Core);
goto leave;
}
err = ksba_cms_set_reader_writer (cms, reader, writer);
if (err)
{
log_debug ("ksba_cms_set_reader_writer failed: %s\n",
ksba_strerror (err));
rc = map_ksba_err (err);
goto leave;
}
/* We are going to create signed data with data as encap. content */
err = ksba_cms_set_content_type (cms, 0, KSBA_CT_ENVELOPED_DATA);
if (!err)
err = ksba_cms_set_content_type (cms, 1, KSBA_CT_ENCRYPTED_DATA);
if (err)
{
log_debug ("ksba_cms_set_content_type failed: %s\n",
ksba_strerror (err));
rc = map_ksba_err (err);
goto leave;
}
/* gather certificates of recipients and store them in the CMS object */
cert = get_default_recipient ();
if (!cert)
{
log_error ("no default recipient found\n");
rc = seterr (General_Error);
goto leave;
}
/* err = ksba_cms_add_signer (cms, cert); */
/* if (err) */
/* { */
/* log_debug ("ksba_cms_add_signer failed: %s\n", ksba_strerror (err)); */
/* rc = map_ksba_err (err); */
/* goto leave; */
/* } */
cert = NULL; /* cms does now own the certificate */
/* Set the hash algorithm we are going to use */
err = ksba_cms_add_digest_algo (cms, "1.3.14.3.2.26" /*SHA-1*/);
if (err)
{
log_debug ("ksba_cms_add_digest_algo failed: %s\n", ksba_strerror (err));
rc = map_ksba_err (err);
goto leave;
}
/* Prepare hashing (actually we are figuring out what we have set above)*/
data_md = gcry_md_open (0, 0);
if (!data_md)
{
rc = map_gcry_err (gcry_errno());
log_error ("md_open failed: %s\n", gcry_strerror (-1));
goto leave;
}
for (i=0; (algoid=ksba_cms_get_digest_algo_list (cms, i)); i++)
{
algo = gcry_md_map_name (algoid);
if (!algo)
{
log_error ("unknown hash algorithm `%s'\n", algoid? algoid:"?");
rc = GNUPG_Bug;
goto leave;
}
gcry_md_enable (data_md, algo);
}
signer = 0;
do
{
err = ksba_cms_build (cms, &stopreason);
if (err)
{
log_debug ("ksba_cms_build failed: %s\n", ksba_strerror (err));
rc = map_ksba_err (err);
goto leave;
}
log_debug ("ksba_cms_build - stop reason %d\n", stopreason);
if (stopreason == KSBA_SR_BEGIN_DATA)
{
}
else if (stopreason == KSBA_SR_NEED_SIG)
{ /* calculate the signature for all signers */
GCRY_MD_HD md;
algo = GCRY_MD_SHA1;
signer = 0;
md = gcry_md_open (algo, 0);
if (!md)
{
log_error ("md_open failed: %s\n", gcry_strerror (-1));
goto leave;
}
ksba_cms_set_hash_function (cms, HASH_FNC, md);
rc = ksba_cms_hash_signed_attrs (cms, signer);
if (rc)
{
log_debug ("hashing signed attrs failed: %s\n",
ksba_strerror (rc));
gcry_md_close (md);
goto leave;
}
{ /* This is all an temporary hack */
char *sigval;
cert = NULL;
if (!cert)
{
log_error ("oops - failed to get cert again\n");
rc = seterr (General_Error);
goto leave;
}
sigval = NULL;
rc = gpgsm_create_cms_signature (cert, md, algo, &sigval);
if (rc)
{
ksba_cert_release (cert);
goto leave;
}
err = ksba_cms_set_sig_val (cms, signer, sigval);
xfree (sigval);
if (err)
{
log_error ("failed to store the signature: %s\n",
ksba_strerror (err));
rc = map_ksba_err (err);
goto leave;
}
}
}
}
while (stopreason != KSBA_SR_READY);
log_info ("signature created\n");
leave:
ksba_cms_release (cms);
gpgsm_destroy_writer (b64writer);
gpgsm_destroy_reader (b64reader);
keydb_release (kh);
gcry_md_close (data_md);
if (data_fp)
fclose (data_fp);
return rc;
}

View File

@ -591,6 +591,7 @@ main ( int argc, char **argv)
memset (&ctrl, 0, sizeof ctrl);
ctrl.no_server = 1;
ctrl.status_fd = -1; /* not status output */
ctrl.autodetect_encoding = 1;
/* set the default option file */
if (default_config )
@ -661,7 +662,10 @@ main ( int argc, char **argv)
case aVerify: set_cmd (&cmd, aVerify); break;
case oArmor: opt.armor = 1; opt.no_armor=0; break;
case oNoArmor: opt.no_armor=1; opt.armor=0; break;
case oNoArmor:
ctrl.autodetect_encoding = 0;
opt.no_armor=1; opt.armor=0;
break;
case oOutput: opt.outfile = pargs.r.ret_str; break;
case oQuiet: opt.quiet = 1; break;
case oNoTTY: /* fixme:tty_no_terminal(1);*/ break;

View File

@ -45,7 +45,7 @@ struct {
int fingerprint; /* list fingerprints in all key listings */
int armor; /* force base64 armoring */
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 */
@ -89,9 +89,20 @@ struct server_control_s {
int status_fd; /* only for non-server mode */
struct server_local_s *server_local;
int with_colons; /* use column delimited output format */
int autodetect_encoding; /* try to detect the input encoding */
int is_pem; /* Is in PEM format */
int is_base64; /* is in plain base-64 format */
int create_base64; /* Create base64 encoded output */
int create_pem; /* create PEM output */
};
typedef struct server_control_s *CTRL;
/* data structure osed in base64.c */
typedef struct base64_context_s *Base64Context;
/*-- gpgsm.c --*/
void gpgsm_exit (int rc);
@ -107,6 +118,14 @@ char *gpgsm_get_fingerprint_hexstring (KsbaCert cert, int algo);
char *gpgsm_get_keygrip (KsbaCert cert, char *array);
char *gpgsm_get_keygrip_hexstring (KsbaCert cert);
/*-- base64.c --*/
int gpgsm_create_reader (Base64Context *ctx,
CTRL ctrl, FILE *fp, KsbaReader *r_reader);
void gpgsm_destroy_reader (Base64Context ctx);
int gpgsm_create_writer (Base64Context *ctx,
CTRL ctrl, FILE *fp, KsbaWriter *r_writer);
void gpgsm_destroy_writer (Base64Context ctx);
/*-- certdump.c --*/
void gpgsm_dump_cert (const char *text, KsbaCert cert);

View File

@ -34,208 +34,6 @@
#include "keydb.h"
#include "i18n.h"
struct reader_cb_parm_s {
FILE *fp;
unsigned char line[1024];
int linelen;
int readpos;
int have_lf;
unsigned long line_counter;
int identified;
int is_pem;
int stop_seen;
struct {
int idx;
unsigned char val;
int stop_seen;
} base64;
};
/* static unsigned char bintoasc[] = */
/* "ABCDEFGHIJKLMNOPQRSTUVWXYZ" */
/* "abcdefghijklmnopqrstuvwxyz" */
/* "0123456789+/"; */
static unsigned char asctobin[256] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff
};
static int
reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
{
struct reader_cb_parm_s *parm = cb_value;
size_t n;
int c, c2;
*nread = 0;
if (!buffer)
return -1; /* not supported */
next:
if (!parm->linelen)
{
/* read an entire line or up to the size of the buffer */
parm->line_counter++;
parm->have_lf = 0;
for (n=0; n < DIM(parm->line);)
{
c = getc (parm->fp);
if (c == EOF)
{
if (ferror (parm->fp))
return -1;
break;
}
parm->line[n++] = c;
if (c == '\n')
{
parm->have_lf = 1;
/* FIXME: we need to skip overlong lines while detecting
the dashed lines */
break;
}
}
parm->linelen = n;
if (!n)
return -1; /* eof */
parm->readpos = 0;
}
if (!parm->identified)
{
if (parm->line_counter == 1 && !parm->have_lf)
{
/* first line too long - assume DER encoding */
parm->is_pem = 0;
}
else if (parm->line_counter == 1 && parm->linelen && *parm->line == 0x30)
{
/* the very first bytes does pretty much look like a SEQUENCE tag*/
parm->is_pem = 0;
}
else if ( parm->have_lf && !strncmp (parm->line, "-----BEGIN ", 11)
&& strncmp (parm->line+11, "PGP ", 4) )
{
/* Fixme: we must only compare if the line really starts at
the beginning */
parm->is_pem = 1;
parm->linelen = parm->readpos = 0;
}
else
{
parm->linelen = parm->readpos = 0;
goto next;
}
parm->identified = 1;
parm->base64.stop_seen = 0;
parm->base64.idx = 0;
}
n = 0;
if (parm->is_pem)
{
if (parm->have_lf && !strncmp (parm->line, "-----END ", 9))
{
parm->identified = 0;
parm->linelen = parm->readpos = 0;
/* let us return 0 */
}
else if (parm->stop_seen)
{ /* skip the rest of the line */
parm->linelen = parm->readpos = 0;
}
else
{
int idx = parm->base64.idx;
unsigned char val = parm->base64.val;
while (n < count && parm->readpos < parm->linelen )
{
c = parm->line[parm->readpos++];
if (c == '\n' || c == ' ' || c == '\r' || c == '\t')
continue;
if (c == '=')
{ /* pad character: stop */
if (idx == 1)
buffer[n++] = val;
parm->stop_seen = 1;
break;
}
if( (c = asctobin[(c2=c)]) == 255 )
{
log_error (_("invalid radix64 character %02x skipped\n"),
c2);
continue;
}
switch (idx)
{
case 0:
val = c << 2;
break;
case 1:
val |= (c>>4)&3;
buffer[n++] = val;
val = (c<<4)&0xf0;
break;
case 2:
val |= (c>>2)&15;
buffer[n++] = val;
val = (c<<6)&0xc0;
break;
case 3:
val |= c&0x3f;
buffer[n++] = val;
break;
}
idx = (idx+1) % 4;
}
if (parm->readpos == parm->linelen)
parm->linelen = parm->readpos = 0;
parm->base64.idx = idx;
parm->base64.val = val;
}
}
else
{ /* DER encoded */
while (n < count && parm->readpos < parm->linelen)
buffer[n++] = parm->line[parm->readpos++];
if (parm->readpos == parm->linelen)
parm->linelen = parm->readpos = 0;
}
*nread = n;
return 0;
}
static void
store_cert (KsbaCert cert)
@ -268,34 +66,23 @@ int
gpgsm_import (CTRL ctrl, int in_fd)
{
int rc;
KsbaReader reader = NULL;
Base64Context b64reader = NULL;
KsbaReader reader;
KsbaCert cert = NULL;
struct reader_cb_parm_s rparm;
FILE *fp = NULL;
memset (&rparm, 0, sizeof rparm);
rparm.fp = fdopen ( dup (in_fd), "rb");
if (!rparm.fp)
fp = fdopen ( dup (in_fd), "rb");
if (!fp)
{
log_error ("fdopen() failed: %s\n", strerror (errno));
rc = seterr (IO_Error);
goto leave;
}
/* setup a skaba reader which uses a callback function so that we can
strip off a base64 encoding when necessary */
reader = ksba_reader_new ();
if (!reader)
{
rc = seterr (Out_Of_Core);
goto leave;
}
rc = ksba_reader_set_cb (reader, reader_cb, &rparm );
rc = gpgsm_create_reader (&b64reader, ctrl, fp, &reader);
if (rc)
{
ksba_reader_release (reader);
rc = map_ksba_err (rc);
log_error ("can't create reader: %s\n", gnupg_strerror (rc));
goto leave;
}
@ -318,9 +105,9 @@ gpgsm_import (CTRL ctrl, int in_fd)
leave:
ksba_cert_release (cert);
ksba_reader_release (reader);
if (rparm.fp)
fclose (rparm.fp);
gpgsm_destroy_reader (b64reader);
if (fp)
fclose (fp);
return rc;
}

View File

@ -81,6 +81,43 @@ rc_to_assuan_status (int rc)
}
static void
reset_notify (ASSUAN_CONTEXT ctx)
{
}
static void
input_notify (ASSUAN_CONTEXT ctx, const char *line)
{
CTRL ctrl = assuan_get_pointer (ctx);
ctrl->autodetect_encoding = 0;
ctrl->is_pem = 0;
ctrl->is_base64 = 0;
if (strstr (line, "--armor"))
ctrl->is_pem = 1;
else if (strstr (line, "--base64"))
ctrl->is_base64 = 1;
else if (strstr (line, "--binary"))
;
else
ctrl->autodetect_encoding = 0;
}
static void
output_notify (ASSUAN_CONTEXT ctx, const char *line)
{
CTRL ctrl = assuan_get_pointer (ctx);
ctrl->create_pem = 0;
ctrl->create_base64 = 0;
if (strstr (line, "--armor"))
ctrl->create_pem = 1;
else if (strstr (line, "--base64"))
ctrl->create_base64 = 1; /* just the raw output */
}
/* RECIPIENT <userID>
@ -103,7 +140,7 @@ cmd_recipient (ASSUAN_CONTEXT ctx, char *line)
}
/* ENCRYPT [armor]
/* ENCRYPT
Do the actual encryption process. Takes the plaintext from the INPUT
command, writes to the ciphertext to the file descriptor set with
@ -115,16 +152,28 @@ cmd_recipient (ASSUAN_CONTEXT ctx, char *line)
This command should in general not fail, as all necessary checks
have been done while setting the recipients. The input and output
pipes are closed.
The optional armor parameter may be used to request base64 encoded
output. */
pipes are closed. */
static int
cmd_encrypt (ASSUAN_CONTEXT ctx, char *line)
{
int inp_fd, out_fd;
FILE *out_fp;
int rc;
return set_error (Not_Implemented, "fixme");
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_encrypt (assuan_get_pointer (ctx), inp_fd, out_fp);
fclose (out_fp);
return rc_to_assuan_status (rc);
}
/* DECRYPT
@ -172,7 +221,7 @@ cmd_verify (ASSUAN_CONTEXT ctx, char *line)
/* SIGN [--detached]
Sign the data set with the INPUT command and write it to the sink
set by OUTPUT. with "--detached" specified, a detached signature is
set by OUTPUT. With "--detached" specified, a detached signature is
created (surprise). */
static int
cmd_sign (ASSUAN_CONTEXT ctx, char *line)
@ -330,6 +379,10 @@ gpgsm_server (void)
gpgsm_exit (2);
}
assuan_register_reset_notify (ctx, reset_notify);
assuan_register_input_notify (ctx, input_notify);
assuan_register_output_notify (ctx, output_notify);
assuan_set_pointer (ctx, &ctrl);
ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local);
ctrl.server_local->assuan_ctx = ctx;

View File

@ -35,14 +35,6 @@
#include "i18n.h"
struct reader_cb_parm_s {
FILE *fp;
};
static void
hash_data (int fd, GCRY_MD_HD md)
{
@ -112,19 +104,17 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
{
int i, rc;
KsbaError err;
KsbaWriter writer = NULL;
Base64Context b64writer = NULL;
KsbaWriter writer;
KsbaCMS cms = NULL;
KsbaStopReason stopreason;
KsbaCert cert;
KEYDB_HANDLE kh = NULL;
GCRY_MD_HD data_md = NULL;
struct reader_cb_parm_s rparm;
int signer;
const char *algoid;
int algo;
memset (&rparm, 0, sizeof rparm);
if (!detached)
{
rc = seterr (Not_Implemented);
@ -140,25 +130,10 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
goto leave;
}
rparm.fp = fdopen ( dup (data_fd), "rb");
if (!rparm.fp)
{
log_error ("fdopen() failed: %s\n", strerror (errno));
rc = seterr (IO_Error);
goto leave;
}
writer = ksba_writer_new ();
if (!writer)
{
rc = seterr (Out_Of_Core);
goto leave;
}
rc = ksba_writer_set_file (writer, out_fp);
rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer);
if (rc)
{
ksba_writer_release (writer);
rc = map_ksba_err (rc);
log_error ("can't create writer: %s\n", gnupg_strerror (rc));
goto leave;
}
@ -357,10 +332,8 @@ gpgsm_sign (CTRL ctrl, int data_fd, int detached, FILE *out_fp)
leave:
ksba_cms_release (cms);
ksba_writer_release (writer);
gpgsm_destroy_writer (b64writer);
keydb_release (kh);
gcry_md_close (data_md);
if (rparm.fp)
fclose (rparm.fp);
return rc;
}

View File

@ -34,11 +34,6 @@
#include "keydb.h"
#include "i18n.h"
struct reader_cb_parm_s {
FILE *fp;
};
/* FIXME: Move this to jnlib */
static char *
strtimestamp (time_t atime)
@ -46,9 +41,9 @@ strtimestamp (time_t atime)
char *buffer = xmalloc (15);
if (atime < 0)
{
strcpy (buffer, "????" "-??" "-??");
}
strcpy (buffer, "????" "-??" "-??");
else if (!atime)
strcpy (buffer, "none");
else
{
struct tm *tp;
@ -62,38 +57,6 @@ strtimestamp (time_t atime)
/* FIXME: We need to write a generic reader callback which should be able
to detect and convert base-64 */
static int
reader_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
{
struct reader_cb_parm_s *parm = cb_value;
size_t n;
int c = 0;
*nread = 0;
if (!buffer)
return -1; /* not supported */
for (n=0; n < count; n++)
{
c = getc (parm->fp);
if (c == EOF)
{
if ( ferror (parm->fp) )
return -1;
if (n)
break; /* return what we have before an EOF */
return -1;
}
*(byte *)buffer++ = c;
}
*nread = n;
return 0;
}
/* fixme: duplicated from import.c */
static void
store_cert (KsbaCert cert)
@ -192,21 +155,19 @@ int
gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
{
int i, rc;
Base64Context b64reader = NULL;
KsbaError err;
KsbaReader reader = NULL;
KsbaWriter writer = NULL;
KsbaReader reader;
KsbaCMS cms = NULL;
KsbaStopReason stopreason;
KsbaCert cert;
KEYDB_HANDLE kh;
GCRY_MD_HD data_md = NULL;
struct reader_cb_parm_s rparm;
int signer;
const char *algoid;
int algo;
int is_detached;
memset (&rparm, 0, sizeof rparm);
FILE *fp = NULL;
kh = keydb_new (0);
if (!kh)
@ -217,29 +178,18 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
}
rparm.fp = fdopen ( dup (in_fd), "rb");
if (!rparm.fp)
fp = fdopen ( dup (in_fd), "rb");
if (!fp)
{
log_error ("fdopen() failed: %s\n", strerror (errno));
rc = seterr (IO_Error);
goto leave;
}
/* setup a skaba reader which uses a callback function so that we can
strip off a base64 encoding when necessary */
reader = ksba_reader_new ();
writer = ksba_writer_new ();
if (!reader || !writer)
{
rc = seterr (Out_Of_Core);
goto leave;
}
rc = ksba_reader_set_cb (reader, reader_cb, &rparm );
rc = gpgsm_create_reader (&b64reader, ctrl, fp, &reader);
if (rc)
{
ksba_reader_release (reader);
rc = map_ksba_err (rc);
log_error ("can't create reader: %s\n", gnupg_strerror (rc));
goto leave;
}
@ -250,7 +200,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
goto leave;
}
err = ksba_cms_set_reader_writer (cms, reader, writer);
err = ksba_cms_set_reader_writer (cms, reader, NULL);
if (err)
{
log_debug ("ksba_cms_set_reader_writer failed: %s\n",
@ -454,9 +404,9 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
char *buf, *fpr, *tstr;
fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
tstr = strtimestamp ( 42 /*fixme: get right time */);
tstr = strtimestamp (sigtime);
buf = xmalloc ( strlen(fpr) + strlen (tstr) + 100);
sprintf (buf, "%s %s %lu", fpr, tstr, (unsigned long)42 );
sprintf (buf, "%s %s %lu", fpr, tstr, (unsigned long)sigtime );
xfree (tstr);
xfree (fpr);
gpgsm_status (ctrl, STATUS_VALIDSIG, buf);
@ -498,11 +448,11 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd)
leave:
ksba_cms_release (cms);
ksba_reader_release (reader);
gpgsm_destroy_reader (b64reader);
keydb_release (kh);
gcry_md_close (data_md);
if (rparm.fp)
fclose (rparm.fp);
if (fp)
fclose (fp);
return rc;
}