예제 #1
0
void _cdk_free_signature(cdk_pkt_signature_t sig)
{
	cdk_desig_revoker_t r;
	size_t nsig;

	if (!sig)
		return;

	nsig = cdk_pk_get_nsig(sig->pubkey_algo);
	_cdk_free_mpibuf(nsig, sig->mpi);

	cdk_subpkt_free(sig->hashed);
	sig->hashed = NULL;
	cdk_subpkt_free(sig->unhashed);
	sig->unhashed = NULL;
	while (sig->revkeys) {
		r = sig->revkeys->next;
		cdk_free(sig->revkeys);
		sig->revkeys = r;
	}
	cdk_free(sig);
}
예제 #2
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;
}
예제 #3
0
static cdk_error_t
read_signature (cdk_stream_t inp, size_t pktlen, cdk_pkt_signature_t sig)
{
  size_t nbytes;
  size_t i, size, nsig;
  cdk_error_t rc;

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

  if (DEBUG_PKT)
    _cdk_log_debug ("read_signature: %d octets\n", pktlen);

  if (pktlen < 16)
    return CDK_Inv_Packet;
  sig->version = cdk_stream_getc (inp);
  if (sig->version < 2 || sig->version > 4)
    return CDK_Inv_Packet_Ver;

  sig->flags.exportable = 1;
  sig->flags.revocable = 1;

  if (sig->version < 4)
    {
      if (cdk_stream_getc (inp) != 5)
	return CDK_Inv_Packet;
      sig->sig_class = cdk_stream_getc (inp);
      sig->timestamp = read_32 (inp);
      sig->keyid[0] = read_32 (inp);
      sig->keyid[1] = read_32 (inp);
      sig->pubkey_algo = _pgp_pub_algo_to_cdk (cdk_stream_getc (inp));
      sig->digest_algo = _pgp_hash_algo_to_gnutls (cdk_stream_getc (inp));
      sig->digest_start[0] = cdk_stream_getc (inp);
      sig->digest_start[1] = cdk_stream_getc (inp);
      nsig = cdk_pk_get_nsig (sig->pubkey_algo);
      if (!nsig)
	return CDK_Inv_Algo;
      for (i = 0; i < nsig; i++)
	{
	  rc = read_mpi (inp, &sig->mpi[i], 0);
	  if (rc)
	    return rc;
	}
    }
  else
    {
      sig->sig_class = cdk_stream_getc (inp);
      sig->pubkey_algo = _pgp_pub_algo_to_cdk (cdk_stream_getc (inp));
      sig->digest_algo = _pgp_hash_algo_to_gnutls (cdk_stream_getc (inp));
      sig->hashed_size = read_16 (inp);
      size = sig->hashed_size;
      sig->hashed = NULL;
      while (size > 0)
	{
	  rc = read_subpkt (inp, &sig->hashed, &nbytes);
	  if (rc)
	    return rc;
	  size -= nbytes;
	}
      sig->unhashed_size = read_16 (inp);
      size = sig->unhashed_size;
      sig->unhashed = NULL;
      while (size > 0)
	{
	  rc = read_subpkt (inp, &sig->unhashed, &nbytes);
	  if (rc)
	    return rc;
	  size -= nbytes;
	}

      rc = parse_sig_subpackets (sig);
      if (rc)
	return rc;

      sig->digest_start[0] = cdk_stream_getc (inp);
      sig->digest_start[1] = cdk_stream_getc (inp);
      nsig = cdk_pk_get_nsig (sig->pubkey_algo);
      if (!nsig)
	return CDK_Inv_Algo;
      for (i = 0; i < nsig; i++)
	{
	  rc = read_mpi (inp, &sig->mpi[i], 0);
	  if (rc)
	    return rc;
	}
    }

  return 0;
}