Exemplo n.º 1
0
/* This functions builds an index of the keyring into a separate file
   with the name keyring.ext.idx. It contains the offset of all public-
   and public subkeys. The format of the file is:
   --------
    4 octets offset of the packet
    8 octets keyid
   20 octets fingerprint
   --------
   We store the keyid and the fingerprint due to the fact we can't get
   the keyid from a v3 fingerprint directly.
*/
static int
keydb_idx_build( const char * file )
{
    cdk_packet_t pkt;
    cdk_stream_t inp, out = NULL;
    byte buf[8], fpr[20];
    char * fname;
    u32 keyid[2];
    int rc, pos;

    if( !file )
        return CDK_Inv_Value;

    pkt = cdk_calloc( 1, sizeof * pkt );
    if( !pkt )
        return CDK_Out_Of_Core;
    
    fname = keydb_idx_mkname( file );
    if( !fname ) {
        rc = CDK_Out_Of_Core;
        goto leave;
    }
  
    rc = cdk_stream_open( file, &inp );
    if( !rc )
        rc = cdk_stream_create( fname, &out );
    if( rc )
        goto leave;

    while( !cdk_stream_eof( inp ) ) {
        pos = cdk_stream_tell( inp );
        rc = cdk_pkt_read( inp, pkt );
        if( rc )
            break;
        if( pkt->pkttype == CDK_PKT_PUBLIC_KEY
            || pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY ) {
            _cdk_u32tobuf( pos, buf );
            cdk_stream_write( out, buf, 4 );
            cdk_pk_get_keyid( pkt->pkt.public_key, keyid );
            _cdk_u32tobuf( keyid[0], buf );
            _cdk_u32tobuf( keyid[1], buf + 4 );
            cdk_stream_write( out, buf, 8 );
            cdk_pk_get_fingerprint( pkt->pkt.public_key, fpr );
            cdk_stream_write( out, fpr, 20 );
        }
        cdk_pkt_free( pkt );
        cdk_pkt_init( pkt );
    }
    cdk_stream_close( out );
 leave:
    cdk_stream_close( inp );
    cdk_free( fname );
    cdk_free( pkt );
    return rc;
}
Exemplo n.º 2
0
Arquivo: kbnode.c Projeto: ares89/vlc
/**
 * cdk_kbnode_write_to_mem_alloc:
 * @node: the key node
 * @r_buf: buffer to hold the raw data
 * @r_buflen: buffer length of the allocated raw data.
 * 
 * The function acts similar to cdk_kbnode_write_to_mem but
 * it allocates the buffer to avoid the lengthy second run.
 */
cdk_error_t
cdk_kbnode_write_to_mem_alloc (cdk_kbnode_t node,
                               byte ** r_buf, size_t * r_buflen)
{
  cdk_kbnode_t n;
  cdk_stream_t s;
  cdk_error_t rc;
  size_t len;

  if (!node || !r_buf || !r_buflen)
    {
      gnutls_assert ();
      return CDK_Inv_Value;
    }

  *r_buf = NULL;
  *r_buflen = 0;

  rc = cdk_stream_tmp_new (&s);
  if (rc)
    {
      gnutls_assert ();
      return rc;
    }

  for (n = node; n; n = n->next)
    {
      /* Skip all packets which cannot occur in a key composition. */
      if (n->pkt->pkttype != CDK_PKT_PUBLIC_KEY &&
          n->pkt->pkttype != CDK_PKT_PUBLIC_SUBKEY &&
          n->pkt->pkttype != CDK_PKT_SECRET_KEY &&
          n->pkt->pkttype != CDK_PKT_SECRET_SUBKEY &&
          n->pkt->pkttype != CDK_PKT_SIGNATURE &&
          n->pkt->pkttype != CDK_PKT_USER_ID &&
          n->pkt->pkttype != CDK_PKT_ATTRIBUTE)
        continue;
      rc = cdk_pkt_write (s, n->pkt);
      if (rc)
        {
          cdk_stream_close (s);
          gnutls_assert ();
          return rc;
        }
    }

  cdk_stream_seek (s, 0);
  len = cdk_stream_get_length (s);
  *r_buf = cdk_calloc (1, len);
  *r_buflen = cdk_stream_read (s, *r_buf, len);
  cdk_stream_close (s);
  return 0;
}
Exemplo n.º 3
0
/**
 * cdk_file_verify:
 * @hd: the session handle
 * @file: the input file
 * @data_file: for detached signature this is the data file and @file is the sig.
 * @output: the output file
 *
 * Verify a signature.
 **/
cdk_error_t
cdk_file_verify (cdk_ctx_t hd, const char *file, const char *data_file,
		 const char *output)
{
  struct stat stbuf;
  cdk_stream_t inp, data;
  char buf[4096];
  int n;
  cdk_error_t rc;

  if (!hd || !file)
    return CDK_Inv_Value;
  if (output && !hd->opt.overwrite && !stat (output, &stbuf))
    return CDK_Inv_Mode;

  rc = cdk_stream_open (file, &inp);
  if (rc)
    return rc;
  if (cdk_armor_filter_use (inp))
    {
      n = cdk_stream_peek (inp, (byte *) buf, DIM (buf) - 1);
      if (!n || n == -1)
	return CDK_EOF;
      buf[n] = '\0';
      if (strstr (buf, "BEGIN PGP SIGNED MESSAGE"))
	{
	  cdk_stream_close (inp);
	  return file_verify_clearsign (hd, file, output);
	}
      cdk_stream_set_armor_flag (inp, 0);
    }

  if (data_file)
    {
      rc = cdk_stream_open (data_file, &data);
      if (rc)
	{
	  cdk_stream_close (inp);
	  return rc;
	}
    }
  else
    data = NULL;

  rc = _cdk_proc_packets (hd, inp, data, NULL, NULL, NULL);

  if (data != NULL)
    cdk_stream_close (data);
  cdk_stream_close (inp);
  return rc;
}
Exemplo n.º 4
0
Arquivo: literal.c Projeto: 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;
}
Exemplo n.º 5
0
/**
 * cdk_stream_tmp_from_mem:
 * @buf: the buffer which shall be written to the temp stream.
 * @buflen: how large the buffer is
 * @r_out: the new stream with the given contents.
 *
 * Creates a new tempory stream with the given contests.
 */
cdk_error_t
cdk_stream_tmp_from_mem (const void *buf, size_t buflen, cdk_stream_t * r_out)
{
    cdk_stream_t s;
    cdk_error_t rc;
    int nwritten;

    *r_out = NULL;
    rc = cdk_stream_tmp_new (&s);
    if (rc)
    {
        gnutls_assert ();
        return rc;
    }

    nwritten = cdk_stream_write (s, buf, buflen);
    if (nwritten == EOF)
    {
        cdk_stream_close (s);
        gnutls_assert ();
        return s->error;
    }
    cdk_stream_seek (s, 0);
    *r_out = s;
    return 0;
}
Exemplo n.º 6
0
cdk_error_t
cdk_keydb_import( cdk_keydb_hd_t hd, cdk_kbnode_t knode, int *result )
{
    cdk_kbnode_t node, chk = NULL;
    cdk_packet_t pkt;
    cdk_stream_t out;
    u32 keyid[2];
    int rc = 0, is_sk = 0;

    if( !hd || !knode )
        return CDK_Inv_Value;
  
    memset( result, 0, 4 * sizeof (int) );
    pkt = find_key_packet( knode, &is_sk );
    if( !pkt )
        return CDK_Inv_Packet;
    result[is_sk] = 1;
    _cdk_pkt_get_keyid( pkt, keyid );
    cdk_keydb_get_bykeyid( hd, keyid, &chk );
    if( chk ) { /* fixme: search for new signatures */
        cdk_kbnode_release( chk );
        return 0;
    }
  
    if( hd->buf ) {
        cdk_stream_close( hd->buf );
        hd->buf = NULL;
    }

    rc = _cdk_stream_append( hd->name, &out );
    if( rc )
        return rc;
  
    for( node = knode; node; node = node->next ) {
        if( node->pkt->pkttype == CDK_PKT_RING_TRUST )
            continue; /* No uniformed syntax for this packet */
        rc = cdk_pkt_write( out, node->pkt );
        if( rc )
            break;
    }
    if( !rc )
        result[is_sk? 3 : 2] = 1;
    cdk_stream_close( out );
    if( !hd->no_cache )
        cdk_keydb_idx_rebuild( hd );
    return rc;
}
Exemplo n.º 7
0
cdk_error_t
_cdk_pkt_write_fp (FILE * out, cdk_packet_t pkt)
{
  cdk_stream_t so;
  cdk_error_t rc;

  rc = _cdk_stream_fpopen (out, 1, &so);
  if (rc)
    return rc;
  rc = cdk_pkt_write (so, pkt);
  cdk_stream_close (so);
  return rc;
}
Exemplo n.º 8
0
/**
 * cdk_keydb_free:
 * @hd: the keydb object
 *
 * Free the keydb object.
 **/
void
cdk_keydb_free( cdk_keydb_hd_t hd )
{
    if( !hd )
        return;
    if( hd->isopen && hd->name ) {
        hd->isopen = 0;
        cdk_free( hd->name );
        hd->name = NULL;
        cdk_stream_close( hd->buf );
        hd->buf = NULL;
    }
    if( !hd->secret ) {
        cdk_stream_close( hd->idx );
        hd->idx = NULL;
    }
    hd->no_cache = 0;
    hd->secret = 0;
    keydb_cache_free( hd->cache );
    hd->cache = NULL;
    keydb_search_free( hd->dbs );
    hd->dbs = NULL;
    cdk_free( hd );
}
Exemplo n.º 9
0
/**
  * gnutls_openpgp_key_deinit - This function deinitializes memory used by a gnutls_openpgp_key_t structure
  * @key: The structure to be initialized
  *
  * This function will deinitialize a key structure. 
  *
  **/
void
gnutls_openpgp_key_deinit (gnutls_openpgp_key_t key)
{
  if (!key)
    return;

  if (key->knode)
    {
      cdk_kbnode_release (key->knode);
      key->knode = NULL;
    }
  if (key->inp)
    cdk_stream_close (key->inp);

  gnutls_free (key);
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
cdk_stream_t
cdk_stream_tmp_from_mem( const void * buf, size_t count )
{
    cdk_stream_t s;
    int nwritten;

    s = cdk_stream_tmp( );
    if( !s )
        return NULL;
  
    nwritten = cdk_stream_write( s, buf, count );
    if( nwritten == EOF ) {
        cdk_stream_close( s );
        return NULL;
    }
    cdk_stream_seek( s, 0 );
    return s;
}
Exemplo n.º 12
0
/**
 * cdk_keydb_idx_rebuild:
 * @hd: key database handle
 *
 * Rebuild the key index files for the given key database.
 **/
cdk_error_t
cdk_keydb_idx_rebuild( cdk_keydb_hd_t hd )
{
    int rc;
  
    if( !hd || !hd->name )
        return CDK_Inv_Value;
    if( hd->secret )
        return 0;
  
    cdk_stream_close( hd->idx );
    if( !hd->idx_name ) {
        hd->idx_name = keydb_idx_mkname( hd->name );
        if( !hd->idx_name )
            return CDK_Out_Of_Core;
    }
    rc = keydb_idx_build( hd->name );
    if( !rc )
        rc = cdk_stream_open( hd->idx_name, &hd->idx );
    return rc;
}
Exemplo n.º 13
0
cdk_error_t
_cdk_stream_append( const char * file, cdk_stream_t * ret_s )
{
    cdk_stream_t s;
    FILE * fp;
    int rc;

    if( !ret_s )
        return CDK_Inv_Value;
    rc = cdk_stream_open( file, &s );
    if( rc )
        return rc;
    fp = fopen( file, "a+b" );
    if( !fp ) {
        cdk_stream_close( s );
        return CDK_File_Error;
    }
    fclose( s->fp );
    s->fp = fp;
    s->flags.write = 1;
    *ret_s = s;
    return 0;
}
Exemplo n.º 14
0
Arquivo: kbnode.c Projeto: ares89/vlc
/**
 * cdk_kbnode_read_from_mem:
 * @ret_node: the new key node
 * @buf: the buffer which stores the key sequence
 * @buflen: the length of the buffer
 *
 * Tries to read a key node from the memory buffer @buf.
 **/
cdk_error_t
cdk_kbnode_read_from_mem (cdk_kbnode_t * ret_node,
                          const byte * buf, size_t buflen)
{
  cdk_stream_t inp;
  cdk_error_t rc;

  if (!ret_node || !buf)
    return CDK_Inv_Value;

  *ret_node = NULL;
  if (!buflen)
    return CDK_Too_Short;

  rc = cdk_stream_tmp_from_mem (buf, buflen, &inp);
  if (rc)
    return rc;
  rc = cdk_keydb_get_keyblock (inp, ret_node);
  if (rc)
    gnutls_assert ();
  cdk_stream_close (inp);
  return rc;
}
Exemplo n.º 15
0
Arquivo: kbnode.c Projeto: ares89/vlc
/**
 * cdk_kbnode_write_to_mem:
 * @node: the key node
 * @buf: the buffer to store the node data
 * @r_nbytes: the new length of the buffer.
 *
 * Tries to write the contents of the key node to the buffer @buf and
 * return the length of it in @r_nbytes. If buf is zero, only the
 * length of the node is calculated and returned in @r_nbytes.
 * Whenever it is possible, the cdk_kbnode_write_to_mem_alloc should be used.
 **/
cdk_error_t
cdk_kbnode_write_to_mem (cdk_kbnode_t node, byte * buf, size_t * r_nbytes)
{
  cdk_kbnode_t n;
  cdk_stream_t s;
  cdk_error_t rc;
  size_t len;

  if (!node || !r_nbytes)
    {
      gnutls_assert ();
      return CDK_Inv_Value;
    }

  rc = cdk_stream_tmp_new (&s);
  if (rc)
    {
      gnutls_assert ();
      return rc;
    }

  for (n = node; n; n = n->next)
    {
      /* Skip all packets which cannot occur in a key composition. */
      if (n->pkt->pkttype != CDK_PKT_PUBLIC_KEY &&
          n->pkt->pkttype != CDK_PKT_PUBLIC_SUBKEY &&
          n->pkt->pkttype != CDK_PKT_SECRET_KEY &&
          n->pkt->pkttype != CDK_PKT_SECRET_SUBKEY &&
          n->pkt->pkttype != CDK_PKT_SIGNATURE &&
          n->pkt->pkttype != CDK_PKT_USER_ID &&
          n->pkt->pkttype != CDK_PKT_ATTRIBUTE)
        continue;
      rc = cdk_pkt_write (s, n->pkt);
      if (rc)
        {
          cdk_stream_close (s);
          gnutls_assert ();
          return rc;
        }
    }

  cdk_stream_seek (s, 0);
  len = cdk_stream_get_length (s);
  if (!buf)
    {
      *r_nbytes = len;          /* Only return the length of the buffer */
      cdk_stream_close (s);
      return 0;
    }
  if (*r_nbytes < len)
    {
      *r_nbytes = len;
      rc = CDK_Too_Short;
    }
  if (!rc)
    *r_nbytes = cdk_stream_read (s, buf, len);
  else
    gnutls_assert ();
  cdk_stream_close (s);
  return rc;
}
Exemplo n.º 16
0
/**
 * cdk_keydb_open:
 * @hd: keydb object
 * @ret_kr: the STREAM object which contains the data of the keyring
 *
 * Open a STREAM with the contents of the keyring from @hd
 **/
cdk_error_t
cdk_keydb_open( cdk_keydb_hd_t hd, cdk_stream_t * ret_kr )
{
    int rc = 0, ec;

    if( !hd || !ret_kr )
        return CDK_Inv_Value;

    if( hd->type == CDK_DBTYPE_DATA && hd->buf )
        cdk_stream_seek( hd->buf, 0 );
    else if( hd->type == CDK_DBTYPE_PK_KEYRING
             || hd->type == CDK_DBTYPE_SK_KEYRING ) {
        if( !hd->isopen && hd->name ) {
            rc = cdk_stream_open( hd->name, &hd->buf );
            if( rc )
                goto leave;
            if( cdk_armor_filter_use( hd->buf ) )
                cdk_stream_set_armor_flag( hd->buf, 0 );
            hd->isopen = 1;
            cdk_free( hd->idx_name );
            hd->idx_name = keydb_idx_mkname( hd->name );
            if( !hd->idx_name ) {
                rc = CDK_Out_Of_Core;
                goto leave;
            }
            ec = cdk_stream_open( hd->idx_name, &hd->idx );
            if( ec && !hd->secret ) {
                rc = keydb_idx_build( hd->name );
                if( !rc )
                    rc = cdk_stream_open( hd->idx_name, &hd->idx );
                if( !rc )
                    _cdk_log_debug( "create key index table\n" );
                if( rc ) {
                    /* this is no real error, it just means we can't create
                       the index at the given directory. maybe we've no write
                       access. in this case, we simply disable the index. */
                    _cdk_log_debug( "disable key index table\n" );
                    rc = 0;
                    hd->no_cache = 1;
                }
            }
        }
        else {
            /* We use the cache to search keys, so we always rewind the
               STREAM. Except when the _NEXT search mode is used because
               this mode is an enumeration and no seeking is needed. */
            if( !hd->search ||
                (hd->search && hd->dbs->type != CDK_DBSEARCH_NEXT) )
                cdk_stream_seek( hd->buf, 0 );
        }
    }
    else
        return CDK_Inv_Mode;
  
 leave:
    if( rc ) {
        cdk_stream_close( hd->buf );
        hd->buf = NULL;
    }
    *ret_kr = hd->buf;
    return rc;
}
Exemplo n.º 17
0
/**
 * gnutls_openpgp_privkey_import:
 * @key: The structure to store the parsed key.
 * @data: The RAW or BASE64 encoded key.
 * @format: One of #gnutls_openpgp_crt_fmt_t elements.
 * @password: not used for now
 * @flags: should be zero
 *
 * This function will convert the given RAW or Base64 encoded key to
 * the native gnutls_openpgp_privkey_t format.  The output will be
 * stored in 'key'.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
 **/
int
gnutls_openpgp_privkey_import (gnutls_openpgp_privkey_t key,
			       const gnutls_datum_t * data,
			       gnutls_openpgp_crt_fmt_t format,
			       const char *password, unsigned int flags)
{
  cdk_stream_t inp;
  cdk_packet_t pkt;
  int rc;

  if (data->data == NULL || data->size == 0)
    {
      gnutls_assert ();
      return GNUTLS_E_OPENPGP_GETKEY_FAILED;
    }

  if (format == GNUTLS_OPENPGP_FMT_RAW)
    {
      rc = cdk_kbnode_read_from_mem (&key->knode, data->data, data->size);
      if (rc != 0)
	{
	  rc = _gnutls_map_cdk_rc (rc);
	  gnutls_assert ();
	  return rc;
	}
    }
  else
    {
      rc = cdk_stream_tmp_from_mem (data->data, data->size, &inp);
      if (rc != 0)
	{
	  rc = _gnutls_map_cdk_rc (rc);
	  gnutls_assert ();
	  return rc;
	}

      if (cdk_armor_filter_use (inp))
	{
	  rc = cdk_stream_set_armor_flag (inp, 0);
	  if (rc != 0)
	    {
	      rc = _gnutls_map_cdk_rc (rc);
	      cdk_stream_close (inp);
	      gnutls_assert ();
	      return rc;
	    }
	}

      rc = cdk_keydb_get_keyblock (inp, &key->knode);
      cdk_stream_close (inp);

      if (rc != 0)
	{
	  rc = _gnutls_map_cdk_rc (rc);
	  gnutls_assert ();
	  return rc;
	}
    }

  /* Test if the import was successful. */
  pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_SECRET_KEY);
  if (pkt == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_OPENPGP_GETKEY_FAILED;
    }

  return 0;
}
Exemplo n.º 18
0
static int
literal_decode( void * opaque, FILE * in, FILE * out )
{
    literal_filter_t * pfx = opaque;
    cdk_stream_t si, so;
    CDK_PACKET pkt;
    cdk_pkt_literal_t pt;
    byte buf[8192];
    size_t nread;
    int rc, bufsize;

    _cdk_log_debug( "literal filter: decode\n" );
  
    if (!pfx || !in || !out)
        return CDK_Inv_Value;

    si = _cdk_stream_fpopen( in, STREAMCTL_READ );
    if (!si)
        return CDK_Out_Of_Core;
    so = _cdk_stream_fpopen( out, STREAMCTL_WRITE );
    if( !so ) {
        cdk_stream_close( si );
        return CDK_Out_Of_Core;
    }
    cdk_pkt_init( &pkt );
    rc = cdk_pkt_read( si, &pkt );
    if( pkt.pkttype != CDK_PKT_LITERAL ) {
        if( pkt.pkttype )
            cdk_pkt_free( &pkt );
        return rc;
    }
    pt = pkt.pkt.literal;
    pfx->mode = pt->mode;
    pfx->filename = cdk_strdup( pt->name? pt->name : " " );
    if( !pfx->filename ) {
        cdk_pkt_free( &pkt );
        return CDK_Out_Of_Core;
    }
    while( !feof( in ) ) {
        _cdk_log_debug( "partial on=%d size=%lu\n",
                        pfx->blkmode.on, pfx->blkmode.size );
        if( pfx->blkmode.on )
            bufsize = pfx->blkmode.size;
        else
            bufsize = pt->len < sizeof buf-1? pt->len : sizeof buf-1;
        nread = cdk_stream_read( pt->buf, buf, bufsize );
        if( nread == EOF ) {
            rc = CDK_File_Error;
            break;
        }
        if( pfx->md )
            cdk_md_write (pfx->md, buf, nread);
        cdk_stream_write( so, buf, nread );
        pt->len -= nread;
        if( pfx->blkmode.on ) {
            pfx->blkmode.size = _cdk_pkt_read_len( in, &pfx->blkmode.on );
            if( pfx->blkmode.size == (size_t)EOF )
                return CDK_Inv_Packet;
        }
        if( pt->len <= 0 && !pfx->blkmode.on )
            break;
    }
    cdk_stream_close( si );
    cdk_stream_close( so );
    cdk_pkt_free( &pkt );
    return rc;
}
Exemplo n.º 19
0
/**
 * gnutls_openpgp_keyring_import:
 * @keyring: The structure to store the parsed key.
 * @data: The RAW or BASE64 encoded keyring.
 * @format: One of #gnutls_openpgp_keyring_fmt elements.
 *
 * This function will convert the given RAW or Base64 encoded keyring
 * to the native #gnutls_openpgp_keyring_t format.  The output will be
 * stored in 'keyring'.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
 **/
int
gnutls_openpgp_keyring_import(gnutls_openpgp_keyring_t keyring,
			      const gnutls_datum_t * data,
			      gnutls_openpgp_crt_fmt_t format)
{
	cdk_error_t err;
	cdk_stream_t input = NULL;
	size_t raw_len = 0;
	uint8_t *raw_data = NULL;
	unsigned free_data = 0;

	if (data->data == NULL || data->size == 0) {
		gnutls_assert();
		return GNUTLS_E_OPENPGP_GETKEY_FAILED;
	}

	_gnutls_debug_log("PGP: keyring import format '%s'\n",
			  format ==
			  GNUTLS_OPENPGP_FMT_RAW ? "raw" : "base64");

	/* Create a new stream from the given data, decode it, and import
	 * the raw database. This to avoid using opencdk streams which are
	 * not thread safe.
	 */
	if (format == GNUTLS_OPENPGP_FMT_BASE64) {
		size_t seen = 0;

		err =
		    cdk_stream_tmp_from_mem(data->data, data->size,
					    &input);
		if (err == 0)
			err = cdk_stream_set_armor_flag(input, 0);
		if (err) {
			gnutls_assert();
			err = _gnutls_map_cdk_rc(err);
			goto error;
		}

		raw_len = cdk_stream_get_length(input);
		if (raw_len == 0) {
			gnutls_assert();
			err = GNUTLS_E_BASE64_DECODING_ERROR;
			goto error;
		}

		raw_data = gnutls_malloc(raw_len);
		if (raw_data == NULL) {
			gnutls_assert();
			err = GNUTLS_E_MEMORY_ERROR;
			goto error;
		}

		do {
			err =
			    cdk_stream_read(input, raw_data + seen,
					    raw_len - seen);

			if (err > 0)
				seen += err;
		}
		while (seen < raw_len && err != EOF && err > 0);

		raw_len = seen;
		if (raw_len == 0) {
			gnutls_assert();
			err = GNUTLS_E_BASE64_DECODING_ERROR;
			goto error;
		}

		free_data = 1;
	} else {		/* RAW */
		raw_len = data->size;
		raw_data = data->data;
	}

	err =
	    cdk_keydb_new_from_mem(&keyring->db, 0, 0, raw_data, raw_len);
	if (err)
		gnutls_assert();

	if (free_data) {
		err = _gnutls_map_cdk_rc(err);
		goto error;
	}

	return _gnutls_map_cdk_rc(err);

      error:
	gnutls_free(raw_data);
	cdk_stream_close(input);

	return err;
}
Exemplo n.º 20
0
static cdk_error_t
literal_decode (void *data, FILE * in, FILE * out)
{
  literal_filter_t *pfx = data;
  cdk_stream_t si, so;
  cdk_packet_t pkt;
  cdk_pkt_literal_t pt;
  byte buf[BUFSIZE];
  ssize_t nread;
  int bufsize;
  cdk_error_t rc;

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

  if (!pfx || !in || !out)
    return CDK_Inv_Value;

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

  cdk_pkt_new (&pkt);
  rc = cdk_pkt_read (si, pkt);
  if (rc || pkt->pkttype != CDK_PKT_LITERAL)
    {
      cdk_pkt_release (pkt);
      cdk_stream_close (si);
      return !rc ? CDK_Inv_Packet : rc;
    }

  rc = _cdk_stream_fpopen (out, STREAMCTL_WRITE, &so);
  if (rc)
    {
      cdk_pkt_release (pkt);
      cdk_stream_close (si);
      return rc;
    }

  pt = pkt->pkt.literal;
  pfx->mode = pt->mode;

  if (pfx->filename && pt->namelen > 0)
    {
      /* The name in the literal packet is more authorative. */
      cdk_free (pfx->filename);
      pfx->filename = dup_trim_filename (pt->name);
    }
  else if (!pfx->filename && pt->namelen > 0)
    pfx->filename = dup_trim_filename (pt->name);
  else if (!pt->namelen && !pfx->filename && pfx->orig_filename)
    {
      /* In this case, we need to derrive the output file name
         from the original name and cut off the OpenPGP extension.
         If this is not possible, we return an error. */
      if (!stristr (pfx->orig_filename, ".gpg") &&
          !stristr (pfx->orig_filename, ".pgp") &&
          !stristr (pfx->orig_filename, ".asc"))
        {
          cdk_pkt_release (pkt);
          cdk_stream_close (si);
          cdk_stream_close (so);
          _cdk_log_debug
            ("literal filter: no file name and no PGP extension\n");
          return CDK_Inv_Mode;
        }
      _cdk_log_debug ("literal filter: derrive file name from original\n");
      pfx->filename = dup_trim_filename (pfx->orig_filename);
      pfx->filename[strlen (pfx->filename) - 4] = '\0';
    }

  while (!feof (in))
    {
      _cdk_log_debug ("literal_decode: part on %d size %lu\n",
                      (int) pfx->blkmode.on, (unsigned long)pfx->blkmode.size);
      if (pfx->blkmode.on)
        bufsize = pfx->blkmode.size;
      else
        bufsize = pt->len < DIM (buf) ? pt->len : DIM (buf);
      nread = cdk_stream_read (pt->buf, buf, bufsize);
      if (nread == EOF)
        {
          rc = CDK_File_Error;
          break;
        }
      if (pfx->md_initialized)
        _gnutls_hash (&pfx->md, buf, nread);
      cdk_stream_write (so, buf, nread);
      pt->len -= nread;
      if (pfx->blkmode.on)
        {
          pfx->blkmode.size = _cdk_pkt_read_len (in, &pfx->blkmode.on);
          if ((ssize_t) pfx->blkmode.size == EOF)
            return CDK_Inv_Packet;
        }
      if (pt->len <= 0 && !pfx->blkmode.on)
        break;
    }

  cdk_stream_close (si);
  cdk_stream_close (so);
  cdk_pkt_release (pkt);
  return rc;
}
Exemplo n.º 21
0
/**
  * gnutls_openpgp_key_export - This function will export a RAW or BASE64 encoded key
  * @key: Holds the key.
  * @format: One of gnutls_openpgp_key_fmt_t elements.
  * @output_data: will contain the key base64 encoded or raw
  * @output_data_size: holds the size of output_data (and will be replaced by the actual size of parameters)
  *
  * This function will convert the given key to RAW or Base64 format.
  * If the buffer provided is not long enough to hold the output, then
  * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
  *
  * Returns 0 on success.
  *
  **/
int
gnutls_openpgp_key_export (gnutls_openpgp_key_t key,
			   gnutls_openpgp_key_fmt_t format,
			   void *output_data, size_t * output_data_size)
{
  int rc;
  size_t input_data_size = *output_data_size;

  rc = cdk_kbnode_write_to_mem (key->knode, output_data, output_data_size);
  if (rc)
    {
      rc = _gnutls_map_cdk_rc (rc);
      gnutls_assert ();
      return rc;
    }

  if (format == GNUTLS_OPENPGP_FMT_BASE64)
    {
      cdk_stream_t s;

      s = cdk_stream_tmp_from_mem (output_data, *output_data_size);
      if (s == NULL)
	{
	  gnutls_assert ();
	  return GNUTLS_E_MEMORY_ERROR;
	}

      cdk_stream_tmp_set_mode (s, 1);
      rc = cdk_stream_set_armor_flag (s, CDK_ARMOR_PUBKEY);
      if (rc)
	{
	  rc = _gnutls_map_cdk_rc (rc);
	  gnutls_assert ();
	  cdk_stream_close (s);
	  return rc;
	}


      *output_data_size = input_data_size;

      rc = cdk_stream_read (s, output_data, *output_data_size);
      if (rc == EOF)
	{
	  gnutls_assert ();
	  cdk_stream_close (s);
	  return GNUTLS_E_INTERNAL_ERROR;
	}

      *output_data_size = rc;
      if (*output_data_size != cdk_stream_get_length (s))
	{
	  *output_data_size = cdk_stream_get_length (s);
	  cdk_stream_close (s);
	  gnutls_assert ();
	  return GNUTLS_E_SHORT_MEMORY_BUFFER;
	}

      cdk_stream_close (s);
    }

  return 0;
}
Exemplo n.º 22
0
static cdk_error_t
file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output)
{
  cdk_stream_t inp = NULL, out = NULL, tmp = NULL;
  digest_hd_st md;
  char buf[512], chk[512];
  const char *s;
  int i, is_signed = 0, nbytes;
  int digest_algo = 0;
  int err;
  cdk_error_t rc;

  memset(&md, 0, sizeof(md));

  if (output)
    {
      rc = cdk_stream_create (output, &out);
      if (rc)
	return rc;
    }

  rc = cdk_stream_open (file, &inp);
  if (rc)
    {
      if (output)
	cdk_stream_close (out);
      return rc;
    }

  s = "-----BEGIN PGP SIGNED MESSAGE-----";
  while (!cdk_stream_eof (inp))
    {
      nbytes = _cdk_stream_gets (inp, buf, DIM (buf) - 1);
      if (!nbytes || nbytes == -1)
	break;
      if (!strncmp (buf, s, strlen (s)))
	{
	  is_signed = 1;
	  break;
	}
    }

  if (cdk_stream_eof (inp) && !is_signed)
    {
      rc = CDK_Armor_Error;
      goto leave;
    }

  while (!cdk_stream_eof (inp))
    {
      nbytes = _cdk_stream_gets (inp, buf, DIM (buf) - 1);
      if (!nbytes || nbytes == -1)
	break;
      if (nbytes == 1)		/* Empty line */
	break;
      else if (!strncmp (buf, "Hash: ", 6))
	{
	  for (i = 0; digest_table[i].name; i++)
	    {
	      if (!strcmp (buf + 6, digest_table[i].name))
		{
		  digest_algo = digest_table[i].algo;
		  break;
		}
	    }
	}
    }

  if (digest_algo && _gnutls_hash_get_algo_len (digest_algo) <= 0)
    {
      rc = CDK_Inv_Algo;
      goto leave;
    }

  if (!digest_algo)
    digest_algo = GNUTLS_DIG_MD5;

  err = _gnutls_hash_init (&md, digest_algo);
  if (err < 0)
    {
      rc = map_gnutls_error (err);
      goto leave;
    }

  s = "-----BEGIN PGP SIGNATURE-----";
  while (!cdk_stream_eof (inp))
    {
      nbytes = _cdk_stream_gets (inp, buf, DIM (buf) - 1);
      if (!nbytes || nbytes == -1)
	break;
      if (!strncmp (buf, s, strlen (s)))
	break;
      else
	{
	  cdk_stream_peek (inp, (byte *) chk, DIM (chk) - 1);
	  i = strncmp (chk, s, strlen (s));
	  if (strlen (buf) == 0 && i == 0)
	    continue;		/* skip last '\n' */
	  _cdk_trim_string (buf, i == 0 ? 0 : 1);
	  _gnutls_hash (&md, buf, strlen (buf));
	}
      if (!strncmp (buf, "- ", 2))	/* FIXME: handle it recursive. */
	memmove (buf, buf + 2, nbytes - 2);
      if (out)
	{
	  if (strstr (buf, "\r\n"))
	    buf[strlen (buf) - 2] = '\0';
	  cdk_stream_write (out, buf, strlen (buf));
	  _cdk_stream_puts (out, _cdk_armor_get_lineend ());
	}
    }

  /* We create a temporary stream object to store the
     signature data in there. */
  rc = cdk_stream_tmp_new (&tmp);
  if (rc)
    goto leave;

  s = "-----BEGIN PGP SIGNATURE-----\n";
  _cdk_stream_puts (tmp, s);
  while (!cdk_stream_eof (inp))
    {
      nbytes = _cdk_stream_gets (inp, buf, DIM (buf) - 1);
      if (!nbytes || nbytes == -1)
	break;
      if (nbytes < (int) (DIM (buf) - 3))
	{
	  buf[nbytes - 1] = '\n';
	  buf[nbytes] = '\0';
	}
      cdk_stream_write (tmp, buf, nbytes);
    }

  /* FIXME: This code is not very elegant. */
  cdk_stream_tmp_set_mode (tmp, STREAMCTL_READ);
  cdk_stream_seek (tmp, 0);
  cdk_stream_set_armor_flag (tmp, 0);
  cdk_stream_read (tmp, NULL, 0);

  /* the digest handle will be closed there. */
  rc = _cdk_proc_packets (hd, tmp, NULL, NULL, NULL, &md);

leave:
  _gnutls_hash_deinit (&md, NULL);
  cdk_stream_close (out);
  cdk_stream_close (tmp);
  cdk_stream_close (inp);
  return rc;
}
Exemplo n.º 23
0
/**
 * cdk_keygen_save: save the generated keys to disk
 * @hd: the keygen object
 * @pub: name of the file to store the public key
 * @sec: name of the file to store the secret key
 *
 **/
cdk_error_t
cdk_keygen_save( cdk_keygen_ctx_t hd, const char * pubf, const char * secf )
{
    cdk_stream_t out = NULL;
    CDK_PACKET pkt;
    int rc;

    hd->key[0].pk = pk_create( hd, 0 );
    if( !hd->key[0].pk )
        return CDK_Inv_Packet;
    hd->key[0].sk = sk_create( hd, 0 );
    if( !hd->key[0].sk )
        return CDK_Inv_Packet;
    hd->id = uid_create( hd );
    if( !hd->id )
        return CDK_Inv_Packet;
    hd->sig = sig_self_create( hd );
    if( !hd->sig )
        return CDK_Inv_Packet;

    rc = cdk_stream_create( pubf, &out );
    if( rc )
        return rc;
  
    cdk_pkt_init( &pkt );
    pkt.pkttype = CDK_PKT_PUBLIC_KEY;
    pkt.pkt.public_key = hd->key[0].pk;
    rc = cdk_pkt_write( out, &pkt );
    if( rc )
        goto fail;
  
    cdk_pkt_init( &pkt );
    pkt.pkttype = CDK_PKT_USER_ID;
    pkt.pkt.user_id = hd->id;
    rc = cdk_pkt_write( out, &pkt );
    if( rc )
        goto fail;

    cdk_pkt_init( &pkt );
    pkt.pkttype = CDK_PKT_SIGNATURE;
    pkt.pkt.signature = hd->sig;
    rc = cdk_pkt_write( out, &pkt );
    if( rc )
        goto fail;

    if( hd->key[1].algo ) {
        cdk_pkt_init( &pkt );
        pkt.pkttype = CDK_PKT_PUBLIC_SUBKEY;
        pkt.pkt.public_key = hd->key[1].pk = pk_create( hd, 1 );
        rc = cdk_pkt_write( out, &pkt );
        if( rc )
            goto fail;

        cdk_pkt_init( &pkt );
        pkt.pkttype = CDK_PKT_SIGNATURE;
        pkt.pkt.signature = sig_subkey_create( hd );
        rc = cdk_pkt_write( out, &pkt );
        cdk_pkt_free( &pkt );
        if( rc )
            goto fail;
    }
  
    cdk_stream_close( out );
    out = NULL;

    rc = cdk_stream_create( secf, &out );
    if( rc )
        goto fail;

    if( hd->protect ) {
        rc = cdk_sk_protect( hd->key[0].sk, hd->pass );
        if( rc )
            goto fail;
    }

    cdk_pkt_init( &pkt );
    pkt.pkttype = CDK_PKT_SECRET_KEY;
    pkt.pkt.secret_key = hd->key[0].sk;
    rc = cdk_pkt_write( out, &pkt );
    if( rc )
        goto fail;

    cdk_pkt_init( &pkt );
    pkt.pkttype = CDK_PKT_USER_ID;
    pkt.pkt.user_id = hd->id;
    rc = cdk_pkt_write( out, &pkt );
    if( rc )
        goto fail;

    cdk_pkt_init( &pkt );
    pkt.pkttype = CDK_PKT_SIGNATURE;
    pkt.pkt.signature = hd->sig;
    rc = cdk_pkt_write( out, &pkt );
    if( rc )
        goto fail;

    if( hd->key[1].algo ) {
        hd->key[1].sk = sk_create( hd, 1 );
        if( hd->protect && (rc = cdk_sk_protect( hd->key[1].sk, hd->pass )) )
            goto fail;
        cdk_pkt_init( &pkt );
        pkt.pkttype = CDK_PKT_SECRET_SUBKEY;
        pkt.pkt.secret_key = hd->key[1].sk;
        rc = cdk_pkt_write( out, &pkt );
        if( rc )
            goto fail;
    }

 fail:
    cdk_stream_close( out );
    return rc;
}