Example #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;
}
Example #2
0
int
cdk_keydb_check_sk( cdk_keydb_hd_t hd, u32 * keyid )
{
    cdk_stream_t db;
    cdk_packet_t pkt;
    u32 kid[2];
    int rc;
    
    if( !hd || !keyid )
        return CDK_Inv_Value;
    if( !hd->secret )
        return CDK_Inv_Mode;
    pkt = cdk_calloc( 1, sizeof * pkt );
    if( !pkt )
        return CDK_Out_Of_Core;
    rc = cdk_keydb_open( hd, &db );
    if( rc )
        return rc;
    cdk_pkt_init( pkt );
    while( !cdk_pkt_read( db, pkt ) ) {
        if( pkt->pkttype != CDK_PKT_SECRET_KEY
            && pkt->pkttype != CDK_PKT_SECRET_SUBKEY )
            goto next;
        cdk_sk_get_keyid( pkt->pkt.secret_key, kid );
        if( KEYID_CMP( kid, keyid ) ) {
            cdk_pkt_free( pkt );
            cdk_free( pkt );
            return 0;
        }
    next:
        cdk_pkt_free( pkt );
        cdk_pkt_init( pkt );
    }
    cdk_free( pkt );
    return CDK_Error_No_Key;
}
Example #3
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;
}
Example #4
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;
}
Example #5
0
cdk_error_t
cdk_keydb_get_keyblock( cdk_stream_t inp, cdk_kbnode_t * r_knode )
{
    cdk_packet_t pkt = NULL;
    cdk_kbnode_t knode = NULL, node = NULL;
    cdk_desig_revoker_t revkeys = NULL;
    u32 keyid[2], main_keyid[2];
    int rc = 0, old_off;
    int key_seen = 0, got_key = 0;

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

    memset( keyid, 0, sizeof keyid );
    memset( main_keyid, 0, sizeof main_keyid );
  
    while( 1 ) {
        pkt = cdk_calloc( 1, sizeof *pkt );
        if( !pkt )
            return CDK_Out_Of_Core;
        old_off = 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
            || pkt->pkttype == CDK_PKT_SECRET_KEY
            || pkt->pkttype == CDK_PKT_SECRET_SUBKEY) {
            if (key_seen && (pkt->pkttype == CDK_PKT_PUBLIC_KEY
                             || pkt->pkttype == CDK_PKT_SECRET_KEY) ) {
                cdk_stream_seek( inp, old_off );
                break;
	    }
            if( pkt->pkttype == CDK_PKT_PUBLIC_KEY
                || pkt->pkttype == CDK_PKT_SECRET_KEY ) {
                _cdk_pkt_get_keyid( pkt, main_keyid );
                key_seen = 1;
            }
            else if( pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY
                     || pkt->pkttype == CDK_PKT_SECRET_SUBKEY ) {
                if( pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY ) {
                    pkt->pkt.public_key->main_keyid[0] = main_keyid[0];
                    pkt->pkt.public_key->main_keyid[1] = main_keyid[1];
		}
                else {
                    pkt->pkt.secret_key->main_keyid[0] = main_keyid[0];
                    pkt->pkt.secret_key->main_keyid[1] = main_keyid[1];
		}
	    }
            /* we save this for the signature */
            _cdk_pkt_get_keyid( pkt, keyid );
            got_key = 1;
	}
        else if( pkt->pkttype == CDK_PKT_USER_ID )
            ;
        else if( pkt->pkttype == CDK_PKT_SIGNATURE ) {
            pkt->pkt.signature->key[0] = keyid[0];
            pkt->pkt.signature->key[1] = keyid[1];
            if( pkt->pkt.signature->sig_class == 0x1F &&
                pkt->pkt.signature->revkeys )
                revkeys = pkt->pkt.signature->revkeys;
	}
        node = cdk_kbnode_new( pkt );
        if( !knode )
            knode = node;
        else
            _cdk_kbnode_add( knode, node );
    }

    if( got_key ) {
        keydb_merge_selfsig( knode, main_keyid );
        rc = keydb_parse_allsigs( knode, NULL, 0 );
        if( revkeys ) {
            node = cdk_kbnode_find( knode, CDK_PKT_PUBLIC_KEY );
            if( node )
                node->pkt->pkt.public_key->revkeys = revkeys;
        }
    }
    *r_knode = got_key ? knode : NULL;
    return rc;
}