Esempio n. 1
0
static cdk_kbnode_t
keydb_find_byusage( cdk_kbnode_t root, int req_usage, int is_pk )
{
    cdk_kbnode_t node;
    int pkttype = 0, req_type = 0;

    req_type = is_pk? CDK_PKT_PUBLIC_KEY : CDK_PKT_SECRET_KEY;
    if( !req_usage )
        return cdk_kbnode_find( root, req_type );

    node = cdk_kbnode_find( root, req_type );
    if( node && !keydb_check_key( node->pkt ) )
        return NULL;

    /* xxx: if there are more subkeys, use the one with the requested
            usage and the newest timestamp. */
    for( node = root; node; node = node->next ) {
        pkttype = node->pkt->pkttype;
        if( is_pk && (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY
                      || node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
            && keydb_check_key( node->pkt )
            && (node->pkt->pkt.public_key->pubkey_usage & req_usage) )
            return node;
        if( !is_pk && (node->pkt->pkttype == CDK_PKT_SECRET_KEY
                       || node->pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
            && keydb_check_key( node->pkt )
            && (node->pkt->pkt.secret_key->pk->pubkey_usage & req_usage) )
            return node;
    }
    return NULL;
}
Esempio n. 2
0
File: kbnode.c Progetto: ares89/vlc
/**
 * cdk_kbnode_find_packet:
 * @node: the key node
 * @pkttype: packet type
 *
 * Same as cdk_kbnode_find but it returns the packet instead of the node.
 **/
cdk_packet_t
cdk_kbnode_find_packet (cdk_kbnode_t node, cdk_packet_type_t pkttype)
{
  cdk_kbnode_t res;

  res = cdk_kbnode_find (node, pkttype);
  return res ? res->pkt : NULL;
}
Esempio n. 3
0
static int
keydb_parse_allsigs( cdk_kbnode_t knode, cdk_keydb_hd_t hd, int check )
{
    cdk_kbnode_t node, kb;
    cdk_pkt_signature_t sig;
    cdk_pkt_pubkey_t pk;
    struct cdk_subpkt_s * s = NULL;
    u32 expiredate = 0, curtime = _cdk_timestamp ();
    u32 keyid[2];
    int rc = 0;

    if( !knode )
        return CDK_Inv_Value;
    if( check && !hd )
        return CDK_Inv_Mode;

    kb = cdk_kbnode_find( knode, CDK_PKT_SECRET_KEY );
    if( kb )
        return 0;

    /* reset */
    for( node = knode; node; node = node->next ) {
        if( node->pkt->pkttype == CDK_PKT_USER_ID )
            node->pkt->pkt.user_id->is_revoked = 0;
        else if( node->pkt->pkttype == CDK_PKT_PUBLIC_KEY
                 || node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY )
            node->pkt->pkt.public_key->is_revoked = 0;
    }

    kb = cdk_kbnode_find( knode, CDK_PKT_PUBLIC_KEY );
    if( !kb )
        return CDK_Inv_Packet;
    cdk_pk_get_keyid( kb->pkt->pkt.public_key, keyid );
  
    for( node = knode; node; node = node->next) {
        if( node->pkt->pkttype == CDK_PKT_SIGNATURE ) {
            sig = node->pkt->pkt.signature;
            /* Revocation certificates for primary keys */
            if( sig->sig_class == 0x20 ) {
                kb = cdk_kbnode_find_prev( knode, node, CDK_PKT_PUBLIC_KEY );
                if( kb ) {
                    kb->pkt->pkt.public_key->is_revoked = 1;
                    if( check )
                        _cdk_pk_check_sig (hd, kb, node, NULL);
		}
                else
                    return CDK_Error_No_Key;
	    }
            /* Revocation certificates for subkeys */
            else if( sig->sig_class == 0x28 ) {
                kb = cdk_kbnode_find_prev (knode, node, CDK_PKT_PUBLIC_SUBKEY);
                if( kb ) {
                    kb->pkt->pkt.public_key->is_revoked = 1;
                    if( check )
                        _cdk_pk_check_sig( hd, kb, node, NULL );
		}
                else
                    return CDK_Error_No_Key;
	    }
            /* Revocation certifcates for user ID's */
            else if( sig->sig_class == 0x30 ) {
                if( sig->keyid[0] != keyid[0] || sig->keyid[1] != keyid[1] )
                    continue; /* revokes an earlier signature, no userID. */
                kb = cdk_kbnode_find_prev (knode, node, CDK_PKT_USER_ID);
                if( kb ) {
                    kb->pkt->pkt.user_id->is_revoked = 1;
                    if( check )
                        _cdk_pk_check_sig( hd, kb, node, NULL );
		}
                else
                    return CDK_Error_No_Key;
	    }
            /* Direct certificates for primary keys */
            else if( sig->sig_class == 0x1F ) {
                kb = cdk_kbnode_find_prev( knode, node, CDK_PKT_PUBLIC_KEY );
                if( kb ) {
                    pk = kb->pkt->pkt.public_key;
                    pk->is_invalid = 0;
                    s = cdk_subpkt_find( node->pkt->pkt.signature->hashed,
                                         CDK_SIGSUBPKT_KEY_EXPIRE );
                    if( s ) {
                        expiredate = _cdk_buftou32( s->d );
                        pk->expiredate = pk->timestamp + expiredate;
                        pk->has_expired = pk->expiredate > curtime? 0 : 1;
		    }
                    if( check )
                        _cdk_pk_check_sig( hd, kb, node, NULL );
		}
                else
                    return CDK_Error_No_Key;
	    }
            /* Direct certificates for subkeys */
            else if( sig->sig_class == 0x18 ) {
                kb = cdk_kbnode_find_prev( knode, node, CDK_PKT_PUBLIC_SUBKEY);
                if( kb ) {
                    pk = kb->pkt->pkt.public_key;
                    pk->is_invalid = 0;
                    s = cdk_subpkt_find( node->pkt->pkt.signature->hashed,
                                         CDK_SIGSUBPKT_KEY_EXPIRE );
                    if( s ) {
                        expiredate = _cdk_buftou32( s->d );
                        pk->expiredate = pk->timestamp + expiredate;
                        pk->has_expired = pk->expiredate > curtime? 0 : 1;
		    }
                    if( check )
                        _cdk_pk_check_sig( hd, kb, node, NULL );
		}
                else
                    return CDK_Error_No_Key;
	    }
	}
    }
    node = cdk_kbnode_find( knode, CDK_PKT_PUBLIC_KEY );
    if( node && node->pkt->pkt.public_key->version == 3 ) {
        /* v3 public keys have no additonal signatures for the key directly.
           we say the key is valid when we have at least a self signature. */
        pk = node->pkt->pkt.public_key;
        for( node = knode; node; node = node->next ) {
            if( is_selfsig( node, keyid ) ) {
                pk->is_invalid = 0;
                break;
            }
        }
    }
    if( node && (node->pkt->pkt.public_key->is_revoked
                 || node->pkt->pkt.public_key->has_expired) ) {
        /* if the primary key has been revoked, mark all subkeys as invalid
           because without a primary key they are not useable */
        for( node = knode; node; node = node->next ) {
            if( node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY )
                node->pkt->pkt.public_key->is_invalid = 1;
        }
    }
    return rc;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}