Example #1
0
cdk_error_t
cdk_keydb_get_sk( cdk_keydb_hd_t hd, u32 * keyid, cdk_pkt_seckey_t* ret_sk )
{
    cdk_kbnode_t snode, node;
    cdk_pkt_seckey_t sk = NULL;
    int rc = 0;

    if( !keyid || !ret_sk )
        return CDK_Inv_Value;
    if( !hd )
        return CDK_Error_No_Keyring;

    rc = cdk_keydb_get_bykeyid( hd, keyid, &snode );
    if( rc )
        goto leave;

    node = keydb_find_bykeyid( snode, keyid );
    if( !node ) {
        rc = CDK_Error_No_Key;
        goto leave;
    }

    sk = node->pkt->pkt.secret_key;
    _cdk_kbnode_clone( node );
    cdk_kbnode_release( snode );

 leave:
    *ret_sk = sk;
    return rc;
}
Example #2
0
/**
 * gnutls_openpgp_keyring_get_crt_count:
 * @ring: is an OpenPGP key ring
 *
 * This function will return the number of OpenPGP certificates
 * present in the given keyring.
 *
 * Returns: the number of subkeys, or a negative error code on error.
 **/
int gnutls_openpgp_keyring_get_crt_count(gnutls_openpgp_keyring_t ring)
{
	cdk_kbnode_t knode;
	cdk_error_t err;
	cdk_keydb_search_t st;
	int ret = 0;

	err =
	    cdk_keydb_search_start(&st, ring->db, CDK_DBSEARCH_NEXT, NULL);
	if (err != CDK_Success) {
		gnutls_assert();
		return _gnutls_map_cdk_rc(err);
	}

	do {
		err = cdk_keydb_search(st, ring->db, &knode);
		if (err != CDK_Error_No_Key && err != CDK_Success) {
			gnutls_assert();
			cdk_keydb_search_release(st);
			return _gnutls_map_cdk_rc(err);
		}

		if (knode_is_pkey(knode))
			ret++;

		cdk_kbnode_release(knode);

	}
	while (err != CDK_Error_No_Key);

	cdk_keydb_search_release(st);
	return ret;
}
Example #3
0
int
_cdk_keydb_get_sk_byusage( cdk_keydb_hd_t hd, const char * name,
                           cdk_pkt_seckey_t* ret_sk, int usage )
{
    cdk_kbnode_t knode = NULL, node = NULL;
    cdk_pkt_seckey_t sk = NULL;
    int rc = 0;

    if( !ret_sk || !usage )
        return CDK_Inv_Value;
    if( !hd )
        return CDK_Error_No_Keyring;

    rc = cdk_keydb_search_start( hd, CDK_DBSEARCH_AUTO, (char *)name );
    if( !rc )
        rc = cdk_keydb_search( hd, &knode );
    if( rc )
        goto leave;
    node = keydb_find_byusage( knode, usage, 0 );
    if( !node ) {
        rc = CDK_Unusable_Key;
        goto leave;
    }

    sk = node->pkt->pkt.secret_key;
    _cdk_kbnode_clone( node );
    cdk_kbnode_release( knode );

leave:
    *ret_sk = sk;
    return rc;
}
Example #4
0
cdk_error_t
cdk_keydb_get_pk( cdk_keydb_hd_t hd, u32 * keyid, cdk_pkt_pubkey_t* r_pk )
{
    cdk_kbnode_t knode = NULL, node = NULL;
    cdk_pkt_pubkey_t pk = NULL;
    int rc = 0;

    if( !keyid || !r_pk )
        return CDK_Inv_Value;
    if( !hd )
        return CDK_Error_No_Keyring;

    rc = cdk_keydb_search_start( hd, !keyid[0]?
                                 CDK_DBSEARCH_SHORT_KEYID : CDK_DBSEARCH_KEYID,
                                 keyid );
    if( !rc )
        rc = cdk_keydb_search( hd, &knode );
    if( rc )
        goto leave;
    node = keydb_find_bykeyid( knode, keyid );
    if( !node ) {
        rc = CDK_Error_No_Key;
        goto leave;
    }
    _cdk_copy_pubkey( &pk, node->pkt->pkt.public_key );
    cdk_kbnode_release( knode );

leave:
    *r_pk = pk;
    return rc;
}
Example #5
0
int
gnutls_openpgp_count_key_names (const gnutls_datum_t * cert)
{
  cdk_kbnode_t knode, p, ctx;
  cdk_packet_t pkt;
  int nuids;

  if (cert == NULL)
    {
      gnutls_assert ();
      return 0;
    }

  if (cdk_kbnode_read_from_mem (&knode, cert->data, cert->size))
    {
      gnutls_assert ();
      return 0;
    }

  ctx = NULL;
  for (nuids = 0;;)
    {
      p = cdk_kbnode_walk (knode, &ctx, 0);
      if (!p)
	break;
      pkt = cdk_kbnode_get_packet (p);
      if (pkt->pkttype == CDK_PKT_USER_ID)
	nuids++;
    }

  cdk_kbnode_release (knode);
  return nuids;
}
Example #6
0
/**
 * gnutls_openpgp_privkey_deinit:
 * @key: The structure to be initialized
 *
 * This function will deinitialize a key structure.
 **/
void gnutls_openpgp_privkey_deinit(gnutls_openpgp_privkey_t key)
{
	if (!key)
		return;

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

	gnutls_free(key);
}
Example #7
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);
}
Example #8
0
/**
 * gnutls_openpgp_keyring_get_crt:
 * @ring: Holds the keyring.
 * @idx: the index of the certificate to export
 * @cert: An uninitialized #gnutls_openpgp_crt_t structure
 *
 * This function will extract an OpenPGP certificate from the given
 * keyring.  If the index given is out of range
 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. The
 * returned structure needs to be deinited.
 *
 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
 **/
int
gnutls_openpgp_keyring_get_crt (gnutls_openpgp_keyring_t ring,
                                unsigned int idx, gnutls_openpgp_crt_t * cert)
{
    cdk_kbnode_t knode;
    cdk_error_t err;
    int ret = 0;
    unsigned int count = 0;
    cdk_keydb_search_t st;

    err = cdk_keydb_search_start (&st, ring->db, CDK_DBSEARCH_NEXT, NULL);
    if (err != CDK_Success)
    {
        gnutls_assert ();
        return _gnutls_map_cdk_rc (err);
    }

    do
    {
        err = cdk_keydb_search (st, ring->db, &knode);
        if (err != CDK_EOF && err != CDK_Success)
        {
            gnutls_assert ();
            cdk_keydb_search_release (st);
            return _gnutls_map_cdk_rc (err);
        }

        if (idx == count && err == CDK_Success)
        {
            ret = gnutls_openpgp_crt_init (cert);
            if (ret == 0)
                (*cert)->knode = knode;
            cdk_keydb_search_release (st);
            return ret;
        }

        if (knode_is_pkey (knode))
            count++;

        cdk_kbnode_release (knode);

    }
    while (err != CDK_EOF);

    cdk_keydb_search_release (st);
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
}
Example #9
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;
}
Example #10
0
int
_cdk_keydb_get_pk_byusage( cdk_keydb_hd_t hd, const char * name,
                           cdk_pkt_pubkey_t* ret_pk, int usage )
{
    cdk_kbnode_t knode, node = NULL;
    cdk_pkt_pubkey_t pk = NULL;
    const char * s;
    int rc = 0;

    if( !ret_pk || !usage )
        return CDK_Inv_Value;
    if( !hd )
        return CDK_Error_No_Keyring;

    rc = cdk_keydb_search_start( hd, CDK_DBSEARCH_AUTO, (char *)name );
    if( !rc )
        rc = cdk_keydb_search( hd, &knode );
    if( rc )
        goto leave;    
    node = keydb_find_byusage( knode, usage, 1 );
    if( !node ) {
        rc = CDK_Unusable_Key;
        goto leave;
    }

    _cdk_copy_pubkey( &pk, node->pkt->pkt.public_key );
    for( node = knode; node; node = node->next ) {
        if( node->pkt->pkttype == CDK_PKT_USER_ID ) {
            s = node->pkt->pkt.user_id->name;
            if( pk && !pk->uid && _cdk_memistr( s, strlen( s ), name ) ) {
                _cdk_copy_userid( &pk->uid, node->pkt->pkt.user_id );
                break;
	    }
	}
    }
    cdk_kbnode_release( knode );

leave:
    *ret_pk = pk;
    return rc;
}
Example #11
0
/**
 * cdk_listkey_next:
 * @ctx: list key context
 * @r_key: the pointer to the new key node object
 *
 * Retrieve the next key from the pattern of the key list context.
 **/
cdk_error_t
cdk_listkey_next( cdk_listkey_t ctx, cdk_kbnode_t * ret_key )
{
    if( !ctx || !ret_key )
        return CDK_Inv_Value;
    if( !ctx->init )
        return CDK_Inv_Mode;

    if( ctx->type && ctx->u.patt[0] == '*' )
        return cdk_keydb_get_keyblock( ctx->inp, ret_key );
    else if( ctx->type ) {
        cdk_kbnode_t node;
        struct cdk_dbsearch_s ks;
        int rc;
        
        for( ;; ) {
            rc = cdk_keydb_get_keyblock( ctx->inp, &node );
            if( rc )
                return rc;
            memset( &ks, 0, sizeof ks );
            ks.type = CDK_DBSEARCH_SUBSTR;
            ks.u.pattern = ctx->u.patt;
            if( find_by_pattern( node, &ks ) ) {
                *ret_key = node;
                return 0;
            }
            cdk_kbnode_release( node );
            node = NULL;
        }
    }
    else {
        if( !ctx->t )
            ctx->t = ctx->u.fpatt;
        else if( ctx->t->next )
            ctx->t = ctx->t->next;
        else
            return CDK_EOF;
        return cdk_keydb_get_bypattern( ctx->db, ctx->t->d, ret_key );
    }
    return CDK_General_Error;
}
Example #12
0
cdk_error_t
cdk_keydb_export( cdk_keydb_hd_t hd, cdk_stream_t out, cdk_strlist_t remusr )
{
    cdk_kbnode_t knode, node;
    cdk_strlist_t r;
    int old_ctb = 0;
    int rc = 0;

    for( r = remusr; r; r = r->next ) {
        rc = cdk_keydb_search_start( hd, CDK_DBSEARCH_AUTO, r->d );
        if( !rc )
            rc = cdk_keydb_search( hd, &knode );
        if( rc )
            break;
        for( node = knode; node; node = node->next ) {
            /* those packets are not intended for the real wolrd */
            if( node->pkt->pkttype == CDK_PKT_RING_TRUST )
                continue;
            /* we never export local signed signatures */
            if( node->pkt->pkttype == CDK_PKT_SIGNATURE &&
                !node->pkt->pkt.signature->flags.exportable )
                continue;
            /* filter out invalid signatures */
            if( node->pkt->pkttype == CDK_PKT_SIGNATURE
                && !KEY_CAN_SIGN (node->pkt->pkt.signature->pubkey_algo) )
                continue;
            if( node->pkt->pkttype == CDK_PKT_PUBLIC_KEY
                && node->pkt->pkt.public_key->version == 3 )
                old_ctb = 1;
            node->pkt->old_ctb = old_ctb;
            rc = cdk_pkt_write( out, node->pkt );
            if( rc )
                break;
	}
        cdk_kbnode_release( knode );
        knode = NULL;
    }
    return rc;
}
Example #13
0
/**
 * cdk_keydb_search:
 * @hd: the keydb object
 * @ks: the keydb search object
 * @ret_key: kbnode object to store the key
 *
 * Search for a key in the given keyring. The search mode is handled
 * via @ks. If the key was found, @ret_key contains the key data.
 **/
cdk_error_t
cdk_keydb_search( cdk_keydb_hd_t hd, cdk_kbnode_t * ret_key )
{
    cdk_stream_t kr = NULL;
    cdk_kbnode_t knode = NULL;
    cdk_dbsearch_t ks;
    u32 off = 0;
    size_t pos = 0;
    int key_found = 0, cache_hit = 0;
    int rc = 0;

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

    *ret_key = NULL;
    hd->search = 1;
    rc = cdk_keydb_open( hd, &kr );
    if( rc )
        return rc;
    rc = keydb_pos_from_cache( hd, hd->dbs, &cache_hit, &off );
    if( rc )
        return rc;
    
    ks = hd->dbs;
    while( !key_found && !rc ) {
        if( cache_hit && ks->type != CDK_DBSEARCH_NEXT )
            cdk_stream_seek( kr, off );
        pos = cdk_stream_tell( kr );
        rc = cdk_keydb_get_keyblock( kr, &knode );
        if( rc ) {
            if( rc == CDK_EOF && knode )
                rc = 0;
            if( !knode && rc == CDK_EOF )
                rc = CDK_Error_No_Key;
            if( rc )
                break;
        }

        switch( ks->type ) {
        case CDK_DBSEARCH_SHORT_KEYID:
        case CDK_DBSEARCH_KEYID:
            key_found = find_by_keyid( knode, ks );
            break;

        case CDK_DBSEARCH_FPR:
            key_found = find_by_fpr( knode, ks );
            break;
          
	case CDK_DBSEARCH_EXACT:
	case CDK_DBSEARCH_SUBSTR:
            key_found = find_by_pattern( knode, ks );
            break;

        case CDK_DBSEARCH_NEXT:
            key_found = knode? 1 : 0;
            break;
	}

        if( key_found ) {
            if( !keydb_cache_find( hd->cache, ks ) )
                keydb_cache_add( hd, ks, pos );
            break;
        }

        cdk_kbnode_release( knode );
        knode = NULL;
    }

    hd->search = 0;
    *ret_key = key_found? knode : NULL;
    return rc;
}
Example #14
0
/*-
 * gnutls_openpgp_get_key - Retrieve a key from the keyring.
 * @key: the destination context to save the key.
 * @keyring: the datum struct that contains all keyring information.
 * @attr: The attribute (keyid, fingerprint, ...).
 * @by: What attribute is used.
 *
 * This function can be used to retrieve keys by different pattern
 * from a binary or a file keyring.
 -*/
int
gnutls_openpgp_get_key (gnutls_datum_t * key,
			gnutls_openpgp_keyring_t keyring, key_attr_t by,
			opaque * pattern)
{
  cdk_kbnode_t knode = NULL;
  unsigned long keyid[2];
  unsigned char *buf;
  void *desc;
  size_t len;
  int rc = 0;
  cdk_keydb_search_t st;

  if (!key || !keyring || by == KEY_ATTR_NONE)
    {
      gnutls_assert ();
      return GNUTLS_E_INVALID_REQUEST;
    }

  memset (key, 0, sizeof *key);

  if (by == KEY_ATTR_SHORT_KEYID)
    {
      keyid[0] = _gnutls_read_uint32 (pattern);
      desc = keyid;
    }
  else if (by == KEY_ATTR_KEYID)
    {
      keyid[0] = _gnutls_read_uint32 (pattern);
      keyid[1] = _gnutls_read_uint32 (pattern + 4);
      desc = keyid;
    }
  else
    desc = pattern;
  rc = cdk_keydb_search_start (&st, keyring->db, by, desc);
  if (!rc)
    rc = cdk_keydb_search (st, keyring->db, &knode);

  cdk_keydb_search_release (st);

  if (rc)
    {
      rc = _gnutls_map_cdk_rc (rc);
      goto leave;
    }

  if (!cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY))
    {
      rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
      goto leave;
    }

  /* We let the function allocate the buffer to avoid
     to call the function twice. */
  rc = cdk_kbnode_write_to_mem_alloc (knode, &buf, &len);
  if (!rc)
    datum_append (key, buf, len);
  gnutls_free (buf);

leave:
  cdk_kbnode_release (knode);
  return rc;
}