Esempio n. 1
0
static int
keydb_idx_parse( cdk_stream_t inp, key_idx_t * r_idx )
{
    key_idx_t idx;
    byte buf[4];
    int i;

    if( !inp || !r_idx )
        return CDK_Inv_Value;
  
    idx = cdk_calloc( 1, sizeof * idx );
    if( !idx )
        return CDK_Out_Of_Core;

    while( !cdk_stream_eof( inp ) ) {
        i = cdk_stream_read( inp, buf, 4 );
        if( i == CDK_EOF )
            break;
        idx->offset = _cdk_buftou32( buf );
        cdk_stream_read( inp, buf, 4 );
        idx->keyid[0] = _cdk_buftou32( buf );
        cdk_stream_read( inp, buf, 4 );
        idx->keyid[1] = _cdk_buftou32( buf );
        cdk_stream_read( inp, idx->fpr, 20 );
#if 0
        _cdk_log_debug( "%08lu: keyid=%08lX fpr=", idx->offset,idx->keyid[1] );
        for( i = 0; i < 20; i++ )
            _cdk_log_debug( "%02X", idx->fpr[i] );
        _cdk_log_debug( "\n" );
#endif
        break; 
    }
    *r_idx = idx;
    return cdk_stream_eof( inp )? CDK_EOF : 0;  
}
Esempio n. 2
0
static cdk_error_t
read_subpkt (cdk_stream_t inp, cdk_subpkt_t * r_ctx, size_t * r_nbytes)
{
  byte c, c1;
  size_t size, nread, n;
  cdk_subpkt_t node;
  cdk_error_t rc;

  if (!inp || !r_nbytes)
    return CDK_Inv_Value;

  if (DEBUG_PKT)
    _cdk_log_debug ("read_subpkt:\n");

  n = 0;
  *r_nbytes = 0;
  c = cdk_stream_getc (inp);
  n++;
  if (c == 255)
    {
      size = read_32 (inp);
      n += 4;
    }
  else if (c >= 192 && c < 255)
    {
      c1 = cdk_stream_getc (inp);
      n++;
      if (c1 == 0)
	return 0;
      size = ((c - 192) << 8) + c1 + 192;
    }
  else if (c < 192)
    size = c;
  else
    return CDK_Inv_Packet;

  node = cdk_subpkt_new (size);
  if (!node)
    return CDK_Out_Of_Core;
  node->size = size;
  node->type = cdk_stream_getc (inp);
  if (DEBUG_PKT)
    _cdk_log_debug (" %d octets %d type\n", node->size, node->type);
  n++;
  node->size--;
  rc = stream_read (inp, node->d, node->size, &nread);
  n += nread;
  if (rc)
    return rc;
  *r_nbytes = n;
  if (!*r_ctx)
    *r_ctx = node;
  else
    cdk_subpkt_add (*r_ctx, node);
  return rc;
}
Esempio n. 3
0
/* This function is exactly like filter_read, except the fact that we can't
   use tmpfile () all the time. That's why we open the real file when there
   is no last filter. */
static cdk_error_t
stream_filter_write (cdk_stream_t s)
{
    struct stream_filter_s *f;
    cdk_error_t rc = 0;

    assert (s);

    if (s->flags.filtrated)
    {
        gnutls_assert ();
        return CDK_Inv_Value;
    }

    for (f = s->filters; f; f = f->next)
    {
        if (!f->flags.enabled)
            continue;
        /* if there is no next filter, create the final output file */
        _cdk_log_debug ("filter [write]: last filter=%d fname=%s\n",
                        f->next ? 1 : 0, s->fname);
        if (!f->next && s->fname)
            f->tmp = fopen (s->fname, "w+b");
        else
            f->tmp = _cdk_tmpfile ();
        if (!f->tmp)
        {
            rc = CDK_File_Error;
            break;
        }
        /* If there is no next filter, flush the cache. We also do this
           when the next filter is the armor filter because this filter
           is special and before it starts, all data should be written. */
        if ((!f->next || f->next->type == fARMOR) && s->cache.size)
        {
            rc = stream_cache_flush (s, f->tmp);
            if (rc)
                break;
        }
        rc = f->fnct (f->opaque, f->ctl, s->fp, f->tmp);
        _cdk_log_debug ("filter [write]: type=%d rc=%d\n", f->type, rc);
        if (!rc)
            rc = stream_fp_replace (s, &f->tmp);
        if (!rc)
            rc = cdk_stream_seek (s, 0);
        if (rc)
        {
            _cdk_log_debug ("filter [close]: fd=%d\n", fileno (f->tmp));
            fclose (f->tmp);
            break;
        }
    }
    return rc;
}
Esempio n. 4
0
/**
 * cdk_pkt_write:
 * @out: the output stream handle
 * @pkt: the packet itself
 *
 * Write the contents of @pkt into the @out stream.
 * Return 0 on success.
 **/
cdk_error_t
cdk_pkt_write (cdk_stream_t out, cdk_packet_t pkt)
{
  cdk_error_t rc;

  if (!out || !pkt)
    return CDK_Inv_Value;

  _cdk_log_debug ("write packet pkttype=%d\n", pkt->pkttype);
  switch (pkt->pkttype)
    {
    case CDK_PKT_LITERAL:
      rc = write_literal (out, pkt->pkt.literal, pkt->old_ctb);
      break;
    case CDK_PKT_ONEPASS_SIG:
      rc = write_onepass_sig (out, pkt->pkt.onepass_sig);
      break;
    case CDK_PKT_MDC:
      rc = write_mdc (out, pkt->pkt.mdc);
      break;
    case CDK_PKT_PUBKEY_ENC:
      rc = write_pubkey_enc (out, pkt->pkt.pubkey_enc, pkt->old_ctb);
      break;
    case CDK_PKT_SIGNATURE:
      rc = write_signature (out, pkt->pkt.signature, pkt->old_ctb);
      break;
    case CDK_PKT_PUBLIC_KEY:
      rc = write_public_key (out, pkt->pkt.public_key, 0, pkt->old_ctb);
      break;
    case CDK_PKT_PUBLIC_SUBKEY:
      rc = write_public_key (out, pkt->pkt.public_key, 1, pkt->old_ctb);
      break;
    case CDK_PKT_COMPRESSED:
      rc = write_compressed (out, pkt->pkt.compressed);
      break;
    case CDK_PKT_SECRET_KEY:
      rc = write_secret_key (out, pkt->pkt.secret_key, 0, pkt->old_ctb);
      break;
    case CDK_PKT_SECRET_SUBKEY:
      rc = write_secret_key (out, pkt->pkt.secret_key, 1, pkt->old_ctb);
      break;
    case CDK_PKT_USER_ID:
    case CDK_PKT_ATTRIBUTE:
      rc = write_user_id (out, pkt->pkt.user_id, pkt->old_ctb, pkt->pkttype);
      break;
    default:
      rc = CDK_Inv_Packet;
      break;
    }

  if (DEBUG_PKT)
    _cdk_log_debug ("write_packet rc=%d pkttype=%d\n", rc, pkt->pkttype);
  return rc;
}
Esempio n. 5
0
static cdk_error_t
sexp_to_sig (cdk_pkt_signature_t sig, gcry_sexp_t sexp)
{
  if (!sig || !sexp)
    return CDK_Inv_Value;

  /* ElGamal signatures are not supported any longer. */
  if (is_ELG (sig->pubkey_algo))
    {
      _cdk_log_debug ("sexp_to_sig: unsupported signature type (ElGamal)\n");
      return CDK_Not_Implemented;
    }  
  
  if (is_RSA (sig->pubkey_algo))
    return sexp_to_mpi (sexp, "s", &sig->mpi[0]);
  else if (is_DSA (sig->pubkey_algo))
    {
      cdk_error_t rc;
      
      rc = sexp_to_mpi (sexp, "r", &sig->mpi[0]);
      if (!rc)
	rc = sexp_to_mpi (sexp, "s", &sig->mpi[1]);
      return rc;
    }
  return CDK_Inv_Algo;
}
Esempio n. 6
0
/**
 * cdk_stream_open: create a new stream based on an existing file.
 * @file: The file to open
 * @ret_s: The new STREAM object
 **/
cdk_error_t
cdk_stream_open( const char * file, cdk_stream_t * ret_s )
{
    cdk_stream_t s;

    if( !file || !ret_s )
        return CDK_Inv_Value;

    _cdk_log_debug( "open stream `%s'\n", file );
    *ret_s = NULL;
    s = cdk_calloc( 1, sizeof *s );
    if( !s )
        return CDK_Out_Of_Core;
    s->fname = cdk_strdup( file );
    if( !s->fname ) {
        cdk_free( s );
        return CDK_Out_Of_Core;
    }
    s->fp = fopen( file, "rb" );
    if( !s->fp ) {
        cdk_free( s->fname );
        cdk_free( s );
        return CDK_File_Error;
    }
    s->flags.write = 0;
    *ret_s = s;
    return 0;
}
Esempio n. 7
0
/**
 * cdk_stream_close: Close a stream and flush all buffers.
 * @s: The STREAM object.
 *
 * This function work different for read or write streams. When the
 * stream is for reading, the filtering is already done and we can
 * simply close the file and all buffers.
 * But for the case it's a write stream, we need to apply all registered
 * filters now. The file is closed in the filter function and not here.
 **/
cdk_error_t
cdk_stream_close( cdk_stream_t s )
{
    struct stream_filter_s * f, * f2;
    int rc = 0;

    if( !s )
        return CDK_Inv_Value;
    
    _cdk_log_debug( "close stream `%s'\n", s->fname? s->fname : "[temp]" );
    
    if( !s->flags.filtrated && !s->error )
        rc = cdk_stream_flush( s );
    if( s->fname || s->flags.temp ) {
        rc = fclose( s->fp );
        s->fp = NULL;
        if( rc )
            rc = CDK_File_Error;
    }
    f = s->filters;
    while( f ) {
        f2 = f->next;
        if( f->fnct )
            f->fnct( f->opaque, STREAMCTL_FREE, NULL, NULL );
        cdk_free( f );
        f = f2;
    }
    if( s->fname ) {
        cdk_free( s->fname );
        s->fname = NULL;
    }
    cdk_free( s );
    return rc;
}
Esempio n. 8
0
/**
 * cdk_stream_set_literal_flag:
 * @s: the stream object
 * @mode: the mode to use (binary, text, unicode)
 * @fname: the file name to store in the packet.
 *
 * In read mode it kicks off the literal decoding routine to
 * unwrap the data from the packet. The @mode parameter is ignored.
 * In write mode the function can be used to wrap the stream data
 * into a literal packet with the given mode and file name.
 **/
cdk_error_t
cdk_stream_set_literal_flag (cdk_stream_t s, cdk_lit_format_t mode,
                             const char *fname)
{
    struct stream_filter_s *f;
    const char *orig_fname;

    _cdk_log_debug ("stream: enable literal mode.\n");

    if (!s)
    {
        gnutls_assert ();
        return CDK_Inv_Value;
    }

    orig_fname = _cdk_stream_get_fname (s);
    f = filter_add (s, _cdk_filter_literal, fLITERAL);
    if (!f)
    {
        gnutls_assert ();
        return CDK_Out_Of_Core;
    }
    f->u.pfx.mode = mode;
    f->u.pfx.filename = fname ? cdk_strdup (fname) : NULL;
    f->u.pfx.orig_filename = orig_fname ? cdk_strdup (orig_fname) : NULL;
    f->ctl = stream_get_mode (s);
    if (s->blkmode > 0)
    {
        f->u.pfx.blkmode.on = 1;
        f->u.pfx.blkmode.size = s->blkmode;
    }
    return 0;
}
Esempio n. 9
0
/**
 * cdk_stream_new: Create a new stream into into the given file.
 * @file: The name of the new file
 * @ret_s: The new STREAM object
 **/
cdk_error_t
cdk_stream_new( const char * file, cdk_stream_t * ret_s )
{
    cdk_stream_t s;

    if( !ret_s )
        return CDK_Inv_Value;

    _cdk_log_debug( "new stream `%s'\n", file? file : "[temp]" );
    *ret_s = NULL;
    s = cdk_calloc( 1, sizeof *s );
    if( !s )
        return CDK_Out_Of_Core;  
    s->flags.write = 1;
    if( !file )
        s->flags.temp = 1;
    else {
        s->fname = cdk_strdup( file );
        if( !s->fname ) {
            cdk_free( s );
            return CDK_Out_Of_Core;
        }
    }
    s->fp = tmpfile( );
    if( !s->fp ) {
        cdk_free( s->fname );
        cdk_free( s );
        return CDK_File_Error;
    }
    *ret_s = s;
    return 0;
}
Esempio n. 10
0
static cdk_error_t
write_onepass_sig (cdk_stream_t out, cdk_pkt_onepass_sig_t sig)
{
  cdk_error_t rc;

  assert (out);
  assert (sig);

  if (sig->version != 3)
    return CDK_Inv_Packet;

  if (DEBUG_PKT)
    _cdk_log_debug ("write_onepass_sig:\n");

  rc = pkt_write_head (out, 0, 13, CDK_PKT_ONEPASS_SIG);
  if (!rc)
    rc = stream_putc (out, sig->version);
  if (!rc)
    rc = stream_putc (out, sig->sig_class);
  if (!rc)
    rc = stream_putc (out, _gnutls_hash_algo_to_pgp (sig->digest_algo));
  if (!rc)
    rc = stream_putc (out, _cdk_pub_algo_to_pgp (sig->pubkey_algo));
  if (!rc)
    rc = write_32 (out, sig->keyid[0]);
  if (!rc)
    rc = write_32 (out, sig->keyid[1]);
  if (!rc)
    rc = stream_putc (out, sig->last);
  return rc;
}
Esempio n. 11
0
static int
write_pubkey_enc (cdk_stream_t out, cdk_pkt_pubkey_enc_t pke, int old_ctb)
{
  size_t size;
  int rc, nenc;

  assert (out);
  assert (pke);

  if (pke->version < 2 || pke->version > 3)
    return CDK_Inv_Packet;
  if (!KEY_CAN_ENCRYPT (pke->pubkey_algo))
    return CDK_Inv_Algo;

  if (DEBUG_PKT)
    _cdk_log_debug ("write_pubkey_enc:\n");

  nenc = cdk_pk_get_nenc (pke->pubkey_algo);
  size = 10 + calc_mpisize (pke->mpi, nenc);
  rc = pkt_write_head (out, old_ctb, size, CDK_PKT_PUBKEY_ENC);
  if (rc)
    return rc;

  rc = stream_putc (out, pke->version);
  if (!rc)
    rc = write_32 (out, pke->keyid[0]);
  if (!rc)
    rc = write_32 (out, pke->keyid[1]);
  if (!rc)
    rc = stream_putc (out, _cdk_pub_algo_to_pgp (pke->pubkey_algo));
  if (!rc)
    rc = write_mpibuf (out, pke->mpi, nenc);
  return rc;
}
Esempio n. 12
0
static cdk_error_t
read_pubkey_enc (cdk_stream_t inp, size_t pktlen, cdk_pkt_pubkey_enc_t pke)
{
  size_t i, nenc;

  if (!inp || !pke)
    return CDK_Inv_Value;

  if (DEBUG_PKT)
    _cdk_log_debug ("read_pubkey_enc: %d octets\n", pktlen);

  if (pktlen < 12)
    return CDK_Inv_Packet;
  pke->version = cdk_stream_getc (inp);
  if (pke->version < 2 || pke->version > 3)
    return CDK_Inv_Packet;
  pke->keyid[0] = read_32 (inp);
  pke->keyid[1] = read_32 (inp);
  if (!pke->keyid[0] && !pke->keyid[1])
    pke->throw_keyid = 1;	/* RFC2440 "speculative" keyID */
  pke->pubkey_algo = _pgp_pub_algo_to_cdk (cdk_stream_getc (inp));
  nenc = cdk_pk_get_nenc (pke->pubkey_algo);
  if (!nenc)
    return CDK_Inv_Algo;
  for (i = 0; i < nenc; i++)
    {
      cdk_error_t rc = read_mpi (inp, &pke->mpi[i], 0);
      if (rc)
	return rc;
    }

  return 0;
}
Esempio n. 13
0
static cdk_error_t
read_public_key (cdk_stream_t inp, size_t pktlen, cdk_pkt_pubkey_t pk)
{
  size_t i, ndays, npkey;

  if (!inp || !pk)
    return CDK_Inv_Value;

  if (DEBUG_PKT)
    _cdk_log_debug ("read_public_key: %d octets\n", pktlen);

  pk->is_invalid = 1;		/* default to detect missing self signatures */
  pk->is_revoked = 0;
  pk->has_expired = 0;

  pk->version = cdk_stream_getc (inp);
  if (pk->version < 2 || pk->version > 4)
    return CDK_Inv_Packet_Ver;
  pk->timestamp = read_32 (inp);
  if (pk->version < 4)
    {
      ndays = read_16 (inp);
      if (ndays)
	pk->expiredate = pk->timestamp + ndays * 86400L;
    }

  pk->pubkey_algo = _pgp_pub_algo_to_cdk (cdk_stream_getc (inp));
  npkey = cdk_pk_get_npkey (pk->pubkey_algo);
  if (!npkey)
    {
      gnutls_assert ();
      _cdk_log_debug ("invalid public key algorithm %d\n", pk->pubkey_algo);
      return CDK_Inv_Algo;
    }
  for (i = 0; i < npkey; i++)
    {
      cdk_error_t rc = read_mpi (inp, &pk->mpi[i], 0);
      if (rc)
	return rc;
    }

  /* This value is just for the first run and will be
     replaced with the actual key flags from the self signature. */
  pk->pubkey_usage = 0;
  return 0;
}
Esempio n. 14
0
/* Activate the block mode for the given stream. */
cdk_error_t
_cdk_stream_set_blockmode (cdk_stream_t s, size_t nbytes)
{
    assert (s);

    _cdk_log_debug ("stream: activate block mode with blocksize %d\n", nbytes);
    s->blkmode = nbytes;
    return 0;
}
Esempio n. 15
0
int
_cdk_stream_set_blockmode( cdk_stream_t s, size_t nbytes )
{
    if( !s )
        return CDK_Inv_Value;
    _cdk_log_debug( "set block mode for stream (size=%d)\n", nbytes );
    s->blkmode = nbytes;  
    return 0;
}
Esempio n. 16
0
/**
 * cdk_stream_write: 
 * @s: The STREAM object
 * @buf: The buffer with the values to write.
 * @count: The size of the buffer.
 *
 * Tries to write count bytes into the stream.
 * In this function we simply write the bytes to the stream. We can't
 * use the filters here because it would mean they have to support
 * partial flushing.
 **/
int
cdk_stream_write (cdk_stream_t s, const void *buf, size_t count)
{
  int nwritten;

  if (!s)
    {
      s->error = CDK_Inv_Value;
      gnutls_assert();
      return EOF;
    }

  if (s->cbs_hd)
    {
      if (s->cbs.write)
	return s->cbs.write (s->cbs_hd, buf, count);
      return 0;
    }

  if (!s->flags.write)
    {
      s->error = CDK_Inv_Mode;	/* this is a read stream */
      gnutls_assert();
      return EOF;
    }

  if (!buf && !count)
    return stream_flush (s);

  if (s->cache.on)
    {
      /* We need to resize the buffer if the additional data wouldn't
         fit into it. We allocate more memory to avoid to resize it the
         next time the function is used. */
      if (s->cache.size + count > s->cache.alloced)
	{
	  byte *old = s->cache.buf;

	  s->cache.buf =
	    cdk_calloc (1, s->cache.alloced + count + STREAM_BUFSIZE);
	  s->cache.alloced += (count + STREAM_BUFSIZE);
	  memcpy (s->cache.buf, old, s->cache.size);
	  cdk_free (old);
	  _cdk_log_debug ("stream: enlarge cache to %d octets\n",
			  s->cache.alloced);
	}
      memcpy (s->cache.buf + s->cache.size, buf, count);
      s->cache.size += count;
      return count;
    }

  nwritten = fwrite (buf, 1, count, s->fp);
  if (!nwritten)
    nwritten = EOF;
  return nwritten;
}
Esempio n. 17
0
/**
 * cdk_stream_create:
 * @file: the filename
 * @ret_s: the object
 *
 * Creates a new stream.
 * The difference to cdk_stream_new is, that no filtering can be used with
 * this kind of stream and everything is written directly to the stream.
 **/
cdk_error_t
cdk_stream_create (const char *file, cdk_stream_t * ret_s)
{
    cdk_stream_t s;

    if (!file || !ret_s)
    {
        gnutls_assert ();
        return CDK_Inv_Value;
    }

    _cdk_log_debug ("create stream `%s'\n", file);
    *ret_s = NULL;
    s = cdk_calloc (1, sizeof *s);
    if (!s)
    {
        gnutls_assert ();
        return CDK_Out_Of_Core;
    }
    s->flags.write = 1;
    s->flags.filtrated = 1;
    s->fname = cdk_strdup (file);
    if (!s->fname)
    {
        cdk_free (s);
        gnutls_assert ();
        return CDK_Out_Of_Core;
    }
    s->fp = fopen (file, "w+b");
    if (!s->fp)
    {
        cdk_free (s->fname);
        cdk_free (s);
        gnutls_assert ();
        return CDK_File_Error;
    }
    _cdk_log_debug ("stream create fd=%d\n", fileno (s->fp));
    *ret_s = s;
    return 0;
}
Esempio n. 18
0
static cdk_error_t
read_mpi (cdk_stream_t inp, bigint_t * ret_m, int secure)
{
  bigint_t m;
  int err;
  byte buf[MAX_MPI_BYTES + 2];
  size_t nread, nbits;
  cdk_error_t rc;

  if (!inp || !ret_m)
    return CDK_Inv_Value;

  *ret_m = NULL;
  nbits = read_16 (inp);
  nread = (nbits + 7) / 8;

  if (nbits > MAX_MPI_BITS || nbits == 0)
    {
      _cdk_log_debug ("read_mpi: too large %d bits\n", nbits);
      return CDK_MPI_Error;	/* Sanity check */
    }

  rc = stream_read (inp, buf + 2, nread, &nread);
  if (!rc && nread != ((nbits + 7) / 8))
    {
      _cdk_log_debug ("read_mpi: too short %d < %d\n", nread,
		      (nbits + 7) / 8);
      return CDK_MPI_Error;
    }

  buf[0] = nbits >> 8;
  buf[1] = nbits >> 0;
  nread += 2;
  err = _gnutls_mpi_scan_pgp (&m, buf, nread);
  if (err < 0)
    return map_gnutls_error (err);

  *ret_m = m;
  return rc;
}
Esempio n. 19
0
/* Helper function to allow to open a stream in different modes. */
cdk_error_t
_cdk_stream_open_mode (const char *file, const char *mode,
                       cdk_stream_t * ret_s)
{
    cdk_stream_t s;

    if (!file || !ret_s)
    {
        gnutls_assert ();
        return CDK_Inv_Value;
    }

    _cdk_log_debug ("open stream `%s'\n", file);
    *ret_s = NULL;
    s = cdk_calloc (1, sizeof *s);
    if (!s)
    {
        gnutls_assert ();
        return CDK_Out_Of_Core;
    }
    s->fname = cdk_strdup (file);
    if (!s->fname)
    {
        cdk_free (s);
        gnutls_assert ();
        return CDK_Out_Of_Core;
    }
    s->fp = fopen (file, mode);
    if (!s->fp)
    {
        cdk_free (s->fname);
        cdk_free (s);
        gnutls_assert ();
        return CDK_File_Error;
    }
    _cdk_log_debug ("open stream fd=%d\n", fileno (s->fp));
    s->flags.write = 0;
    *ret_s = s;
    return 0;
}
Esempio n. 20
0
File: literal.c Progetto: sqs/gnutls
static cdk_error_t
literal_encode (void *data, FILE * in, FILE * out)
{
    literal_filter_t *pfx = data;
    cdk_pkt_literal_t pt;
    cdk_stream_t si;
    cdk_packet_t pkt;
    size_t filelen;
    cdk_error_t rc;

    _cdk_log_debug ("literal filter: encode\n");

    if (!pfx || !in || !out)
        return CDK_Inv_Value;
    if (!pfx->filename)
    {
        pfx->filename = cdk_strdup ("_CONSOLE");
        if (!pfx->filename)
            return CDK_Out_Of_Core;
    }

    rc = _cdk_stream_fpopen (in, STREAMCTL_READ, &si);
    if (rc)
        return rc;

    filelen = strlen (pfx->filename);
    cdk_pkt_new (&pkt);
    pt = pkt->pkt.literal = cdk_calloc (1, sizeof *pt + filelen);
    pt->name = (char *) pt + sizeof (*pt);
    if (!pt)
    {
        cdk_pkt_release (pkt);
        cdk_stream_close (si);
        return CDK_Out_Of_Core;
    }
    memcpy (pt->name, pfx->filename, filelen);
    pt->namelen = filelen;
    pt->name[pt->namelen] = '\0';
    pt->timestamp = (u32) time (NULL);
    pt->mode = intmode_to_char (pfx->mode);
    pt->len = cdk_stream_get_length (si);
    pt->buf = si;
    pkt->old_ctb = 1;
    pkt->pkttype = CDK_PKT_LITERAL;
    pkt->pkt.literal = pt;
    rc = _cdk_pkt_write_fp (out, pkt);

    cdk_pkt_release (pkt);
    cdk_stream_close (si);
    return rc;
}
Esempio n. 21
0
static int
keydb_pos_from_cache( cdk_keydb_hd_t hd, cdk_dbsearch_t ks,
                      int * r_cache_hit, u32 * r_off )
{
    key_table_t c;
    u32 off = 0;
    int cache_hit = 0;

    if( !hd || !r_cache_hit || !r_off )
        return CDK_Inv_Value;
  
    c = keydb_cache_find( hd->cache, ks );
    if( c ) {
        _cdk_log_debug( "found entry in cache.\n" );
        cache_hit = 1;
        off = c->offset;
    }

    if( hd->idx && !c ) {
        if( ks->type == CDK_DBSEARCH_KEYID ) {
            if( keydb_idx_search( hd->idx, ks->u.keyid, NULL, &off ) )
                return CDK_Error_No_Key;
            _cdk_log_debug( "found keyid entry in idx table.\n" );
            cache_hit = 1;
        }
        else if( ks->type == CDK_DBSEARCH_FPR ) {
            if( keydb_idx_search( hd->idx, NULL, ks->u.fpr, &off ) )
                return CDK_Error_No_Key;
            _cdk_log_debug( "found fpr entry in idx table.\n" );
            cache_hit = 1;
        }
    }
    *r_off = off;
    *r_cache_hit = cache_hit;
    return 0;
}
Esempio n. 22
0
/* Here all data from the file handle is passed through all filters.
   The scheme works like this:
   Create a tempfile and use it for the output of the filter. Then the
   original file handle will be closed and replace with the temp handle.
   The file pointer will be set to the begin and the game starts again. */
static int
stream_filter_read( cdk_stream_t s )
{
    struct stream_filter_s * f;
    int rc = 0;

    assert( s );
    
    if( s->flags.filtrated )
        return 0;

    for( f = s->filters; f; f = f->next ) {
        if( !f->flags.enabled )
            continue;
        f->tmp = tmpfile( );
        if( !f->tmp ) {
            rc = CDK_File_Error;
            break;
        }
        rc = f->fnct( f->opaque, f->ctl, s->fp, f->tmp );
        _cdk_log_debug( "filter %s [read]: type=%d rc=%d\n",
                        s->fname? s->fname : "[temp]", f->type, rc );
        if( rc )
            break;
      
        /* if the filter is read-only, do not replace the FP because
           the contents were not altered in any way. */
        if( !f->flags.rdonly ) {
            rc = stream_fp_replace( s, &f->tmp );
            if( rc )
                break;
        }
        else {
            fclose( f->tmp );
            f->tmp = NULL;
        }
        rc = cdk_stream_seek( s, 0 );
        if( rc )
            break;
        /* Disable the filter after it was successfully used. The idea
           is the following: let's say the armor filter was pushed and
           later more filters were added. The second time the filter code
           will be executed, only the new filter should be started but
           not the old because we already used it. */
        f->flags.enabled = 0;
    }
    return rc;
}
Esempio n. 23
0
int
_cdk_filter_text( void * opaque, int ctl, FILE * in, FILE * out )
{
    if( ctl == STREAMCTL_READ )
        return text_encode( opaque, in, out );
    else if( ctl == STREAMCTL_WRITE )
        return text_decode( opaque, in, out );
    else if( ctl == STREAMCTL_FREE ) {
        text_filter_t * tfx = opaque;
        if( tfx ) {
            _cdk_log_debug( "free text filter\n" );
            tfx->lf = NULL;
        }
    }
    return CDK_Inv_Mode;
}
Esempio n. 24
0
static cdk_error_t
write_literal (cdk_stream_t out, cdk_pkt_literal_t pt, int old_ctb)
{
  byte buf[BUFSIZE];
  size_t size;
  cdk_error_t rc;

  assert (out);
  assert (pt);

  /* We consider a packet without a body as an invalid packet.
     At least one octet must be present. */
  if (!pt->len)
    return CDK_Inv_Packet;

  if (DEBUG_PKT)
    _cdk_log_debug ("write_literal:\n");

  size = 6 + pt->namelen + pt->len;
  rc = pkt_write_head (out, old_ctb, size, CDK_PKT_LITERAL);
  if (rc)
    return rc;

  rc = stream_putc (out, pt->mode);
  if (rc)
    return rc;
  rc = stream_putc (out, pt->namelen);
  if (rc)
    return rc;

  if (pt->namelen > 0)
    rc = stream_write (out, pt->name, pt->namelen);
  if (!rc)
    rc = write_32 (out, pt->timestamp);
  if (rc)
    return rc;

  while (!cdk_stream_eof (pt->buf) && !rc)
    {
      rc = stream_read (pt->buf, buf, DIM (buf), &size);
      if (!rc)
	rc = stream_write (out, buf, size);
    }

  wipemem (buf, sizeof (buf));
  return rc;
}
Esempio n. 25
0
static cdk_error_t
write_compressed (cdk_stream_t out, cdk_pkt_compressed_t cd)
{
  cdk_error_t rc;

  assert (out);
  assert (cd);

  if (DEBUG_PKT)
    _cdk_log_debug ("packet: write_compressed\n");

  /* Use an old (RFC1991) header for this packet. */
  rc = pkt_write_head (out, 1, 0, CDK_PKT_COMPRESSED);
  if (!rc)
    rc = stream_putc (out, cd->algorithm);
  return rc;
}
Esempio n. 26
0
static cdk_error_t
write_public_key (cdk_stream_t out, cdk_pkt_pubkey_t pk,
		  int is_subkey, int old_ctb)
{
  int pkttype, ndays = 0;
  size_t npkey = 0, size = 6;
  cdk_error_t rc;

  assert (out);
  assert (pk);

  if (pk->version < 2 || pk->version > 4)
    return CDK_Inv_Packet;

  if (DEBUG_PKT)
    _cdk_log_debug ("write_public_key: subkey=%d\n", is_subkey);

  pkttype = is_subkey ? CDK_PKT_PUBLIC_SUBKEY : CDK_PKT_PUBLIC_KEY;
  npkey = cdk_pk_get_npkey (pk->pubkey_algo);
  if (!npkey)
    return CDK_Inv_Algo;
  if (pk->version < 4)
    size += 2;			/* expire date */
  if (is_subkey)
    old_ctb = 0;
  size += calc_mpisize (pk->mpi, npkey);
  if (old_ctb)
    rc = pkt_write_head2 (out, size, pkttype);
  else
    rc = pkt_write_head (out, old_ctb, size, pkttype);
  if (!rc)
    rc = stream_putc (out, pk->version);
  if (!rc)
    rc = write_32 (out, pk->timestamp);
  if (!rc && pk->version < 4)
    {
      if (pk->expiredate)
	ndays = (u16) ((pk->expiredate - pk->timestamp) / 86400L);
      rc = write_16 (out, ndays);
    }
  if (!rc)
    rc = stream_putc (out, _cdk_pub_algo_to_pgp (pk->pubkey_algo));
  if (!rc)
    rc = write_mpibuf (out, pk->mpi, npkey);
  return rc;
}
Esempio n. 27
0
static int
literal_encode (void * opaque, FILE * in, FILE * out)
{
    literal_filter_t * pfx = opaque;
    cdk_pkt_literal_t pt;
    cdk_stream_t si;
    CDK_PACKET pkt;
    size_t filelen;
    int rc;

    _cdk_log_debug ("literal filter: encode\n");
  
    if (!pfx || !in || !out)
        return CDK_Inv_Value;
  
    if (!pfx->filename) {
        pfx->filename = cdk_strdup ("_CONSOLE");
        if( !pfx->filename )
            return CDK_Out_Of_Core;
    }

    si = _cdk_stream_fpopen (in, STREAMCTL_READ);
    if (!si)
        return CDK_Out_Of_Core;

    filelen = strlen (pfx->filename);
    pt = cdk_calloc (1, sizeof *pt + filelen - 1);
    if (!pt)
        return CDK_Out_Of_Core;
    memcpy (pt->name, pfx->filename, filelen);
    pt->namelen = filelen;
    pt->name[pt->namelen] = '\0';
    pt->timestamp = _cdk_timestamp ();
    pt->mode = pfx->mode ? 't' : 'b';
    pt->len = cdk_stream_get_length (si);
    pt->buf = si;
    cdk_pkt_init (&pkt);
    pkt.old_ctb = pfx->rfc1991? 1 : 0;
    pkt.pkttype = CDK_PKT_LITERAL;
    pkt.pkt.literal = pt;
    rc = _cdk_pkt_write_fp (out, &pkt);

    cdk_free (pt);
    cdk_stream_close (si);
    return rc;
}
Esempio n. 28
0
static cdk_error_t
read_mdc (cdk_stream_t inp, cdk_pkt_mdc_t mdc)
{
  size_t n;
  cdk_error_t rc;

  if (!inp || !mdc)
    return CDK_Inv_Value;

  if (DEBUG_PKT)
    _cdk_log_debug ("read_mdc:\n");

  rc = stream_read (inp, mdc->hash, DIM (mdc->hash), &n);
  if (rc)
    return rc;

  return n != DIM (mdc->hash) ? CDK_Inv_Packet : 0;
}
Esempio n. 29
0
static cdk_error_t
write_mdc (cdk_stream_t out, cdk_pkt_mdc_t mdc)
{
  cdk_error_t rc;

  assert (mdc);
  assert (out);

  if (DEBUG_PKT)
    _cdk_log_debug ("write_mdc:\n");

  /* This packet requires a fixed header encoding */
  rc = stream_putc (out, 0xD3);	/* packet ID and 1 byte length */
  if (!rc)
    rc = stream_putc (out, 0x14);
  if (!rc)
    rc = stream_write (out, mdc->hash, DIM (mdc->hash));
  return rc;
}
Esempio n. 30
0
/* WARNING: tmp should not be closed by the caller. */
static cdk_error_t
stream_fp_replace (cdk_stream_t s, FILE ** tmp)
{
    int rc;

    assert (s);

    _cdk_log_debug ("replace stream fd=%d with fd=%d\n",
                    fileno (s->fp), fileno (*tmp));
    rc = fclose (s->fp);
    if (rc)
    {
        gnutls_assert ();
        return CDK_File_Error;
    }
    s->fp = *tmp;
    *tmp = NULL;
    return 0;
}