Exemple #1
0
/**
 * cdk_sklist_write:
 * @skl: secret keylist
 * @outp: the stream to write in the data
 * @hash: opaque handle for the message digest operations
 * @sigclass: the class of the sig
 * @sigver: version of the sig
 *
 * Complete the sig based on @hash and write all signatures to @outp.
 **/
cdk_error_t
cdk_sklist_write( cdk_keylist_t skl, cdk_stream_t outp, cdk_md_hd_t hash,
		  int sigclass, int sigver )
{
    cdk_keylist_t r = NULL;
    cdk_pkt_signature_t sig = NULL;
    cdk_packet_t pkt;
    cdk_md_hd_t md = NULL;
    byte * mdbuf;
    int rc = 0, digest_algo;

    if( !skl || !outp || !hash )
        return CDK_Inv_Value;

    if( skl->type != CDK_PKT_SECRET_KEY )
        return CDK_Inv_Mode;

    pkt = cdk_calloc( 1, sizeof *pkt );
    if( !pkt )
        return CDK_Out_Of_Core;
    digest_algo = cdk_md_get_algo( hash );
    for( r = skl; r; r = r->next ) {
        sig = cdk_calloc( 1, sizeof *sig );
        if( !sig )
            return CDK_Out_Of_Core;
        sig->version = sigver;
        _cdk_sig_create( r->key.sk->pk, sig );
        if( sig->digest_algo != digest_algo )
            sig->digest_algo = digest_algo;
        sig->sig_class = sigclass;
        md = cdk_md_copy( hash );
        _cdk_hash_sig_data( sig, md );
        cdk_md_final( md );

        mdbuf = cdk_md_read( md, sig->digest_algo );
        rc = cdk_pk_sign( r->key.sk, sig, mdbuf );
        if( rc )
            break;
        cdk_pkt_init( pkt );
        pkt->old_ctb = sig->version == 3? 1 : 0;
        pkt->pkttype = CDK_PKT_SIGNATURE;
        pkt->pkt.signature = sig;
        rc = cdk_pkt_write( outp, pkt );
        cdk_pkt_free( pkt );
        if( rc )
            break;
        cdk_md_close( md );
        md = NULL;
    }
    cdk_free( pkt );
    cdk_md_close( md );
    return rc;
}
Exemple #2
0
/**
 * cdk_kbnode_hash:
 * @node: the key node
 * @hashctx: opaque pointer to the hash context
 * @is_v4: OpenPGP signature (yes=1, no=0)
 * @pkttype: packet type to hash (if zero use the packet type from the node)
 * @flags: flags which depend on the operation
 *
 * Hashes the key node contents. Two modes are supported. If the packet
 * type is used (!= 0) then the function searches the first node with
 * this type. Otherwise the node is seen as a single node and the type
 * is extracted from it.
 **/
cdk_error_t
cdk_kbnode_hash (cdk_kbnode_t node, digest_hd_st * md, int is_v4,
                 cdk_packet_type_t pkttype, int flags)
{
  cdk_packet_t pkt;

  if (!node || !md)
    {
      gnutls_assert ();
      return CDK_Inv_Value;
    }
  if (!pkttype)
    {
      pkt = cdk_kbnode_get_packet (node);
      pkttype = pkt->pkttype;
    }
  else
    {
      pkt = cdk_kbnode_find_packet (node, pkttype);
      if (!pkt)
        {
          gnutls_assert ();
          return CDK_Inv_Packet;
        }
    }

  switch (pkttype)
    {
    case CDK_PKT_PUBLIC_KEY:
    case CDK_PKT_PUBLIC_SUBKEY:
      _cdk_hash_pubkey (pkt->pkt.public_key, md, flags & 1);
      break;

    case CDK_PKT_USER_ID:
      _cdk_hash_userid (pkt->pkt.user_id, is_v4, md);
      break;

    case CDK_PKT_SIGNATURE:
      _cdk_hash_sig_data (pkt->pkt.signature, md);
      break;

    default:
      gnutls_assert ();
      return CDK_Inv_Mode;
    }
  return 0;
}