Esempio n. 1
0
/**
 * cdk_pk_sign:
 * @sk: secret key
 * @sig: signature
 * @md: the message digest
 *
 * Sign the message digest from @md and write the result into @sig.
 **/
cdk_error_t
cdk_pk_sign (cdk_seckey_t sk, cdk_pkt_signature_t sig, const byte *md)
{
  gcry_sexp_t s_skey = NULL, s_sig = NULL, s_hash = NULL;
  byte *encmd = NULL;
  size_t enclen = 0;
  int nbits;
  cdk_error_t rc;
  gcry_error_t err;
  
  if (!sk || !sk->pk || !sig || !md)
    return CDK_Inv_Value;
  
  if (!is_unprotected (sk))
    return CDK_Inv_Mode;
  
  if (!KEY_CAN_SIGN (sig->pubkey_algo))
    return CDK_Inv_Algo;
  
  nbits = cdk_pk_get_nbits (sk->pk);
  rc = _cdk_digest_encode_pkcs1 (&encmd, &enclen, sk->pk->pubkey_algo, md,
				 sig->digest_algo, nbits);
  if (rc)
    return rc;

  rc = seckey_to_sexp (&s_skey, sk);
  if (!rc)
    rc = digest_to_sexp (&s_hash, sig->digest_algo, encmd, enclen);
  if (rc)
    {
      cdk_free (encmd);
      gcry_sexp_release (s_skey);
      return rc;
    }  
  
  err = gcry_pk_sign (&s_sig, s_hash, s_skey);
  if (err)
    rc = map_gcry_error (err);
  else
    {      
      rc = sexp_to_sig (sig, s_sig);
      if (!rc)
	{
	  sig->digest_start[0] = md[0];
	  sig->digest_start[1] = md[1];
	}
    }
  
  gcry_sexp_release (s_skey);
  gcry_sexp_release (s_hash);
  gcry_sexp_release (s_sig);
  cdk_free (encmd);
  return rc;
}
Esempio n. 2
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;
}
Esempio n. 3
0
static cdk_error_t
write_signature (cdk_stream_t out, cdk_pkt_signature_t sig, int old_ctb)
{
  byte *buf;
  size_t nbytes, size, nsig;
  cdk_error_t rc;

  assert (out);
  assert (sig);

  if (!KEY_CAN_SIGN (sig->pubkey_algo))
    return CDK_Inv_Algo;
  if (sig->version < 2 || sig->version > 4)
    return CDK_Inv_Packet;

  if (DEBUG_PKT)
    _cdk_log_debug ("write_signature:\n");

  nsig = cdk_pk_get_nsig (sig->pubkey_algo);
  if (!nsig)
    return CDK_Inv_Algo;
  if (sig->version < 4)
    return write_v3_sig (out, sig, nsig);

  size = 10 + calc_subpktsize (sig->hashed)
    + calc_subpktsize (sig->unhashed) + calc_mpisize (sig->mpi, nsig);
  rc = pkt_write_head (out, 0, size, CDK_PKT_SIGNATURE);
  if (!rc)
    rc = stream_putc (out, 4);
  if (!rc)
    rc = stream_putc (out, sig->sig_class);
  if (!rc)
    rc = stream_putc (out, _cdk_pub_algo_to_pgp (sig->pubkey_algo));
  if (!rc)
    rc = stream_putc (out, _gnutls_hash_algo_to_pgp (sig->digest_algo));
  if (!rc)
    rc = write_16 (out, sig->hashed_size);
  if (!rc)
    {
      buf = _cdk_subpkt_get_array (sig->hashed, 0, &nbytes);
      if (!buf)
	return CDK_Out_Of_Core;
      rc = stream_write (out, buf, nbytes);
      cdk_free (buf);
    }
  if (!rc)
    rc = write_16 (out, sig->unhashed_size);
  if (!rc)
    {
      buf = _cdk_subpkt_get_array (sig->unhashed, 0, &nbytes);
      if (!buf)
	return CDK_Out_Of_Core;
      rc = stream_write (out, buf, nbytes);
      cdk_free (buf);
    }
  if (!rc)
    rc = stream_putc (out, sig->digest_start[0]);
  if (!rc)
    rc = stream_putc (out, sig->digest_start[1]);
  if (!rc)
    rc = write_mpibuf (out, sig->mpi, nsig);
  return rc;
}