Beispiel #1
0
static gboolean
parse_v4_signature_subpackets (const guchar **at,
                               const guchar *end,
                               GcrRecord *record,
                               SigSubpacket *subpkt)
{
	gsize length;
	guint8 sub_type;
	const guchar *stop;

	while (*at != end) {
		if (!read_new_length (at, end, &length) ||
		    !read_byte (at, end, &sub_type) ||
		    length == 0)
			return FALSE;

		/* The length includes the sub_type */
		length--;
		stop = *at + length;
		if (stop > end)
			return FALSE;

		/* Actually parse the sub packets */
		if (!parse_v4_signature_subpacket (at, stop, sub_type, record, subpkt))
			return FALSE;
		if (*at != stop)
			return FALSE;
	}

	return TRUE;
}
Beispiel #2
0
static gboolean
parse_user_attribute (const guchar *beg,
                      const guchar **at,
                      const guchar *end,
                      GcrOpenpgpParseFlags flags,
                      GPtrArray *records)
{
	gsize subpkt_len;
	guint count = 0;
	const guchar *start;
	const guchar *subpkt_beg;
	guint8 subpkt_type;
	gchar *fingerprint;
	gchar *string;
	GcrRecord *record;

	start = *at;
	while (*at != end) {
		subpkt_beg = *at;

		if (!read_new_length (at, end, &subpkt_len) ||
		    !read_byte (at, end, &subpkt_type))
			return FALSE;

		count++;

		if (flags & GCR_OPENPGP_PARSE_ATTRIBUTES) {
			if (!parse_user_attribute_packet (subpkt_beg, at,
			                                  *at + (subpkt_len - 1),
			                                  subpkt_type, records))
				return FALSE;

		/* We already progressed one extra byte for the subpkt_type */
		} else {
			*at += (subpkt_len - 1);
		}
	}

	fingerprint = hash_user_id_or_attribute (start, end);
	string = g_strdup_printf ("%d %d", count, (guint)(*at - start));
	record = _gcr_record_new (GCR_RECORD_SCHEMA_UAT, GCR_RECORD_UAT_MAX, ':');
	_gcr_record_take_raw (record, GCR_RECORD_UAT_FINGERPRINT, fingerprint);
	_gcr_record_take_raw (record, GCR_RECORD_UAT_COUNT_SIZE, string);

	g_ptr_array_add (records, record);
	return TRUE;
}
Beispiel #3
0
static GcrDataError
read_openpgp_packet (const guchar **at,
                     const guchar *end,
                     guint8 *pkt_type,
                     gsize *length)
{
	gboolean new_ctb;
	guint8 ctb;
	gboolean ret;

	if (!read_byte (at, end, &ctb))
		return GCR_ERROR_UNRECOGNIZED;
	if (!(ctb & 0x80))
		return GCR_ERROR_UNRECOGNIZED;

	/* RFC2440 packet format. */
	if (ctb & 0x40) {
		*pkt_type = ctb & 0x3f;
		new_ctb = TRUE;

	/* the old RFC1991 packet format. */
	} else {
		*pkt_type = ctb & 0x3f;
		*pkt_type >>= 2;
		new_ctb = FALSE;
	}

	if (*pkt_type > 63)
		return GCR_ERROR_UNRECOGNIZED;

	if (new_ctb)
		ret = read_new_length (at, end, length);
	else
		ret = read_old_length (at, end, ctb, length);
	if (!ret)
		return GCR_ERROR_UNRECOGNIZED;

	if ((*at) + *length > end)
		return GCR_ERROR_FAILURE;

	return GCR_SUCCESS;
}
Beispiel #4
0
/**
 * cdk_pkt_read:
 * @inp: the input stream
 * @pkt: allocated packet handle to store the packet
 *
 * Parse the next packet on the @inp stream and return its contents in @pkt.
 **/
cdk_error_t
cdk_pkt_read (cdk_stream_t inp, cdk_packet_t pkt)
{
  int ctb, is_newctb;
  int pkttype;
  size_t pktlen = 0, pktsize = 0, is_partial = 0;
  cdk_error_t rc;

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

  ctb = cdk_stream_getc (inp);
  if (cdk_stream_eof (inp) || ctb == EOF)
    return CDK_EOF;
  else if (!ctb)
    return CDK_Inv_Packet;

  pktsize++;
  if (!(ctb & 0x80))
    {
      _cdk_log_info ("cdk_pkt_read: no openpgp data found. "
		     "(ctb=%02X; fpos=%02X)\n", ctb, cdk_stream_tell (inp));
      return CDK_Inv_Packet;
    }

  if (ctb & 0x40)		/* RFC2440 packet format. */
    {
      pkttype = ctb & 0x3f;
      is_newctb = 1;
    }
  else				/* the old RFC1991 packet format. */
    {
      pkttype = ctb & 0x3f;
      pkttype >>= 2;
      is_newctb = 0;
    }

  if (pkttype > 63)
    {
      _cdk_log_info ("cdk_pkt_read: unknown type %d\n", pkttype);
      return CDK_Inv_Packet;
    }

  if (is_newctb)
    read_new_length (inp, &pktlen, &pktsize, &is_partial);
  else
    read_old_length (inp, ctb, &pktlen, &pktsize);

  pkt->pkttype = pkttype;
  pkt->pktlen = pktlen;
  pkt->pktsize = pktsize + pktlen;
  pkt->old_ctb = is_newctb ? 0 : 1;

  rc = 0;
  switch (pkt->pkttype)
    {
    case CDK_PKT_ATTRIBUTE:
      pkt->pkt.user_id = cdk_calloc (1, sizeof *pkt->pkt.user_id
				     + pkt->pktlen + 16 + 1);
      if (!pkt->pkt.user_id)
	return CDK_Out_Of_Core;
      pkt->pkt.user_id->name = (char*)pkt->pkt.user_id + sizeof(*pkt->pkt.user_id);

      rc = read_attribute (inp, pktlen, pkt->pkt.user_id);
      pkt->pkttype = CDK_PKT_ATTRIBUTE;
      break;

    case CDK_PKT_USER_ID:
      pkt->pkt.user_id = cdk_calloc (1, sizeof *pkt->pkt.user_id
				     + pkt->pktlen + 1);
      if (!pkt->pkt.user_id)
	return CDK_Out_Of_Core;
      pkt->pkt.user_id->name = (char*)pkt->pkt.user_id + sizeof(*pkt->pkt.user_id);
      rc = read_user_id (inp, pktlen, pkt->pkt.user_id);
      break;

    case CDK_PKT_PUBLIC_KEY:
      pkt->pkt.public_key = cdk_calloc (1, sizeof *pkt->pkt.public_key);
      if (!pkt->pkt.public_key)
	return CDK_Out_Of_Core;
      rc = read_public_key (inp, pktlen, pkt->pkt.public_key);
      break;

    case CDK_PKT_PUBLIC_SUBKEY:
      pkt->pkt.public_key = cdk_calloc (1, sizeof *pkt->pkt.public_key);
      if (!pkt->pkt.public_key)
	return CDK_Out_Of_Core;
      rc = read_public_subkey (inp, pktlen, pkt->pkt.public_key);
      break;

    case CDK_PKT_SECRET_KEY:
      pkt->pkt.secret_key = cdk_calloc (1, sizeof *pkt->pkt.secret_key);
      if (!pkt->pkt.secret_key)
	return CDK_Out_Of_Core;
      pkt->pkt.secret_key->pk = cdk_calloc (1,
					    sizeof *pkt->pkt.secret_key->pk);
      if (!pkt->pkt.secret_key->pk)
	return CDK_Out_Of_Core;
      rc = read_secret_key (inp, pktlen, pkt->pkt.secret_key);
      break;

    case CDK_PKT_SECRET_SUBKEY:
      pkt->pkt.secret_key = cdk_calloc (1, sizeof *pkt->pkt.secret_key);
      if (!pkt->pkt.secret_key)
	return CDK_Out_Of_Core;
      pkt->pkt.secret_key->pk = cdk_calloc (1,
					    sizeof *pkt->pkt.secret_key->pk);
      if (!pkt->pkt.secret_key->pk)
	return CDK_Out_Of_Core;
      rc = read_secret_subkey (inp, pktlen, pkt->pkt.secret_key);
      break;

    case CDK_PKT_LITERAL:
      pkt->pkt.literal = cdk_calloc (1, sizeof *pkt->pkt.literal);
      if (!pkt->pkt.literal)
	return CDK_Out_Of_Core;
      rc = read_literal (inp, pktlen, &pkt->pkt.literal, is_partial);
      break;

    case CDK_PKT_ONEPASS_SIG:
      pkt->pkt.onepass_sig = cdk_calloc (1, sizeof *pkt->pkt.onepass_sig);
      if (!pkt->pkt.onepass_sig)
	return CDK_Out_Of_Core;
      rc = read_onepass_sig (inp, pktlen, pkt->pkt.onepass_sig);
      break;

    case CDK_PKT_SIGNATURE:
      pkt->pkt.signature = cdk_calloc (1, sizeof *pkt->pkt.signature);
      if (!pkt->pkt.signature)
	return CDK_Out_Of_Core;
      rc = read_signature (inp, pktlen, pkt->pkt.signature);
      break;

    case CDK_PKT_PUBKEY_ENC:
      pkt->pkt.pubkey_enc = cdk_calloc (1, sizeof *pkt->pkt.pubkey_enc);
      if (!pkt->pkt.pubkey_enc)
	return CDK_Out_Of_Core;
      rc = read_pubkey_enc (inp, pktlen, pkt->pkt.pubkey_enc);
      break;

    case CDK_PKT_COMPRESSED:
      pkt->pkt.compressed = cdk_calloc (1, sizeof *pkt->pkt.compressed);
      if (!pkt->pkt.compressed)
	return CDK_Out_Of_Core;
      rc = read_compressed (inp, pktlen, pkt->pkt.compressed);
      break;

    case CDK_PKT_MDC:
      pkt->pkt.mdc = cdk_calloc (1, sizeof *pkt->pkt.mdc);
      if (!pkt->pkt.mdc)
	return CDK_Out_Of_Core;
      rc = read_mdc (inp, pkt->pkt.mdc);
      break;

    default:
      /* Skip all packets we don't understand */
      skip_packet (inp, pktlen);
      break;
    }

  return rc;
}