Esempio n. 1
0
File: verify.c Progetto: gpg/gpgme
/* Parse a TOFU_STATS_LONG line and store it in the last tofu info of SIG.  */
static gpgme_error_t
parse_tofu_stats_long (gpgme_signature_t sig, char *args, int raw)
{
  gpgme_error_t err;
  gpgme_tofu_info_t ti;
  char *p;

  if (!sig->tofu)
    return trace_gpg_error (GPG_ERR_INV_ENGINE); /* No TOFU_USER seen.  */
  for (ti = sig->tofu; ti->next; ti = ti->next)
    ;
  if (ti->description)
    return trace_gpg_error (GPG_ERR_INV_ENGINE); /* Already seen.  */

  err = _gpgme_decode_percent_string (args, &ti->description, 0, 0);
  if (err)
    return err;

  /* Remove the non-breaking spaces.  */
  if (!raw)
    {
      for (p = ti->description; *p; p++)
        if (*p == '~')
          *p = ' ';
    }
  return 0;
}
Esempio n. 2
0
File: verify.c Progetto: gpg/gpgme
/* Parse a TOFU_USER line and put the info into SIG.  */
static gpgme_error_t
parse_tofu_user (gpgme_signature_t sig, char *args)
{
  gpg_error_t err;
  char *tail;
  gpgme_tofu_info_t ti, ti2;

  tail = strchr (args, ' ');
  if (!tail || tail == args)
    return trace_gpg_error (GPG_ERR_INV_ENGINE);  /* No fingerprint.  */
  *tail++ = 0;

  ti = calloc (1, sizeof *ti);
  if (!ti)
    return gpg_error_from_syserror ();

  ti->fpr = strdup (args);
  if (!ti->fpr)
    {
      free (ti);
      return gpg_error_from_syserror ();
    }

  args = tail;
  tail = strchr (args, ' ');
  if (tail == args)
    return trace_gpg_error (GPG_ERR_INV_ENGINE);  /* No addr-spec.  */
  if (tail)
    *tail = 0;

  err = _gpgme_decode_percent_string (args, &ti->address, 0, 0);
  if (err)
    {
      free (ti);
      return err;
    }

  /* Append to the tofu info list.  */
  if (!sig->tofu)
    sig->tofu = ti;
  else
    {
      for (ti2 = sig->tofu; ti2->next; ti2 = ti2->next)
        ;
      ti2->next = ti;
    }

  return 0;
}
Esempio n. 3
0
/* Parse a notation or policy URL subpacket.  If the packet type is
   not known, return no error but NULL in NOTATION.  */
gpgme_error_t
_gpgme_parse_notation(gpgme_sig_notation_t *notationp,
                      int type, int pkflags, int len, char *data)
{
    gpgme_error_t err;
    char *name = NULL;
    int name_len = 0;
    char *value = NULL;
    int value_len = 0;
    gpgme_sig_notation_flags_t flags = 0;
    char *decoded_data;
    unsigned char *bdata;

    /* Type 20: Notation data.  */
    /* Type 26: Policy URL.  */
    if(type != 20 && type != 26)
    {
        *notationp = NULL;
        return 0;
    }

    /* A few simple sanity checks.  */
    if(len > strlen(data))
        return gpg_error(GPG_ERR_INV_ENGINE);

    /* See below for the format of a notation subpacket.  It has at
       least four octets of flags and two times two octets of length
       information.  */
    if(type == 20 && len < 4 + 2 + 2)
        return gpg_error(GPG_ERR_INV_ENGINE);

    err = _gpgme_decode_percent_string(data, &decoded_data, 0, 1);
    if(err)
        return err;
    bdata = (unsigned char *) decoded_data;

    /* Flags common to notation data and policy URL.  */
    if(pkflags & GNUPG_SPK_CRITICAL)
        flags |= GPGME_SIG_NOTATION_CRITICAL;

    /* This information is relevant in parsing multi-octet numbers below:

       3.1. Scalar numbers

       Scalar numbers are unsigned, and are always stored in big-endian
       format.  Using n[k] to refer to the kth octet being interpreted,
       the value of a two-octet scalar is ((n[0] << 8) + n[1]).  The
       value of a four-octet scalar is ((n[0] << 24) + (n[1] << 16) +
       (n[2] << 8) + n[3]).

       From RFC2440: OpenPGP Message Format.  Copyright (C) The Internet
       Society (1998).  All Rights Reserved.  */
#define RFC2440_GET_WORD(chr) ((((int)((unsigned char *)(chr))[0]) << 8) \
			       + ((int)((unsigned char *)(chr))[1]))

    if(type == 20)
    {
        /* 5.2.3.15. Notation Data

        (4 octets of flags, 2 octets of name length (M),
         2 octets of value length (N), M octets of name data,
         N octets of value data)

         [...] The "flags" field holds four octets of flags.
         All undefined flags MUST be zero. Defined flags are:

         First octet: 0x80 = human-readable. [...]
         Other octets:  none.

         From RFC2440: OpenPGP Message Format.  Copyright (C) The
         Internet Society (1998).  All Rights Reserved.  */

        int chr;

        /* First octet of flags.  */
#define RFC2440_SPK20_FLAG1_HUMAN_READABLE 0x80

        chr = *bdata;
        bdata++;

        if(chr & RFC2440_SPK20_FLAG1_HUMAN_READABLE)
            flags |= GPGME_SIG_NOTATION_HUMAN_READABLE;

        /* The second, third and four octet of flags are unused.  */
        bdata++;
        bdata++;
        bdata++;

        name_len = RFC2440_GET_WORD(bdata);
        bdata += 2;

        value_len = RFC2440_GET_WORD(bdata);
        bdata += 2;

        /* Small sanity check.  */
        if(4 + 2 + 2 + name_len + value_len > len)
        {
            free(decoded_data);
            return gpg_error(GPG_ERR_INV_ENGINE);
        }

        name = (char *) bdata;
        bdata += name_len;

        value = (char *) bdata;
    }
    else
    {
        /* Type is 26.  */

        /* NAME is NULL, name_len is 0.  */

        value = (char *) bdata;
        value_len = strlen(value);
    }

    err = _gpgme_sig_notation_create(notationp, name, name_len,
                                     value, value_len, flags);

    free(decoded_data);
    return err;
}
Esempio n. 4
0
File: verify.c Progetto: gpg/gpgme
static gpgme_error_t
parse_notation (gpgme_signature_t sig, gpgme_status_code_t code, char *args)
{
  gpgme_error_t err;
  gpgme_sig_notation_t *lastp = &sig->notations;
  gpgme_sig_notation_t notation = sig->notations;
  char *p;

  if (code == GPGME_STATUS_NOTATION_NAME || code == GPGME_STATUS_POLICY_URL)
    {
      p = strchr (args, ' ');
      if (p)
        *p = '\0';

      /* FIXME: We could keep a pointer to the last notation in the list.  */
      while (notation && notation->value)
	{
	  lastp = &notation->next;
	  notation = notation->next;
	}

      if (notation)
	/* There is another notation name without data for the
	   previous one.  The crypto backend misbehaves.  */
	return trace_gpg_error (GPG_ERR_INV_ENGINE);

      err = _gpgme_sig_notation_create (&notation, NULL, 0, NULL, 0, 0);
      if (err)
	return err;

      if (code == GPGME_STATUS_NOTATION_NAME)
	{
	  err = _gpgme_decode_percent_string (args, &notation->name, 0, 0);
	  if (err)
	    {
	      _gpgme_sig_notation_free (notation);
	      return err;
	    }

	  notation->name_len = strlen (notation->name);

	  /* Set default flags for use with older gpg versions which
           * do not emit a NOTATIONS_FLAG line.  */
	  notation->flags = GPGME_SIG_NOTATION_HUMAN_READABLE;
	  notation->human_readable = 1;
	}
      else
	{
	  /* This is a policy URL.  */

	  err = _gpgme_decode_percent_string (args, &notation->value, 0, 0);
	  if (err)
	    {
	      _gpgme_sig_notation_free (notation);
	      return err;
	    }

	  notation->value_len = strlen (notation->value);
	}
      *lastp = notation;
    }
  else if (code == GPGME_STATUS_NOTATION_FLAGS)
    {
      char *field[2];

      while (notation && notation->next)
	{
	  lastp = &notation->next;
	  notation = notation->next;
	}

      if (!notation || !notation->name)
        { /* There are notation flags without a previous notation name.
           * The crypto backend misbehaves.  */
          return trace_gpg_error (GPG_ERR_INV_ENGINE);
        }
      if (_gpgme_split_fields (args, field, DIM (field)) < 2)
        { /* Required args missing.  */
          return trace_gpg_error (GPG_ERR_INV_ENGINE);
        }
      notation->flags = 0;
      if (atoi (field[0]))
        {
          notation->flags |= GPGME_SIG_NOTATION_CRITICAL;
          notation->critical = 1;
        }
      if (atoi (field[1]))
        {
          notation->flags |= GPGME_SIG_NOTATION_HUMAN_READABLE;
          notation->human_readable = 1;
        }
    }
  else if (code == GPGME_STATUS_NOTATION_DATA)
    {
      int len = strlen (args) + 1;
      char *dest;

      /* FIXME: We could keep a pointer to the last notation in the list.  */
      while (notation && notation->next)
	{
	  lastp = &notation->next;
	  notation = notation->next;
	}

      if (!notation || !notation->name)
	/* There is notation data without a previous notation
	   name.  The crypto backend misbehaves.  */
	return trace_gpg_error (GPG_ERR_INV_ENGINE);

      if (!notation->value)
	{
	  dest = notation->value = malloc (len);
	  if (!dest)
	    return gpg_error_from_syserror ();
	}
      else
	{
	  int cur_len = strlen (notation->value);
	  dest = realloc (notation->value, len + strlen (notation->value));
	  if (!dest)
	    return gpg_error_from_syserror ();
	  notation->value = dest;
	  dest += cur_len;
	}

      err = _gpgme_decode_percent_string (args, &dest, len, 0);
      if (err)
	return err;

      notation->value_len += strlen (dest);
    }
  else
    return trace_gpg_error (GPG_ERR_INV_ENGINE);
  return 0;
}
Esempio n. 5
0
static gpgme_error_t
gpgconf_parse_option (gpgme_conf_opt_t opt,
		      gpgme_conf_arg_t *arg_p, char *line)
{
  gpgme_error_t err;
  char *mark;

  if (!line[0])
    return 0;

  while (line)
    {
      gpgme_conf_arg_t arg;

      mark = strchr (line, ',');
      if (mark)
	*mark = '\0';

      arg = calloc (1, sizeof (*arg));
      if (!arg)
	return gpg_error_from_syserror ();
      *arg_p = arg;
      arg_p = &arg->next;

      if (*line == '\0')
	arg->no_arg = 1;
      else
	{
	  switch (opt->alt_type)
	    {
	      /* arg->value.count is an alias for arg->value.uint32.  */
	    case GPGME_CONF_NONE:
	    case GPGME_CONF_UINT32:
	      arg->value.uint32 = strtoul (line, NULL, 0);
	      break;

	    case GPGME_CONF_INT32:
	      arg->value.uint32 = strtol (line, NULL, 0);
	      break;

	    case GPGME_CONF_STRING:
              /* The complex types below are only here to silent the
                 compiler warning. */
            case GPGME_CONF_FILENAME:
            case GPGME_CONF_LDAP_SERVER:
            case GPGME_CONF_KEY_FPR:
            case GPGME_CONF_PUB_KEY:
            case GPGME_CONF_SEC_KEY:
            case GPGME_CONF_ALIAS_LIST:
	      /* Skip quote character.  */
	      line++;

	      err = _gpgme_decode_percent_string (line, &arg->value.string,
						  0, 0);
	      if (err)
		return err;
	      break;
	    }
	}

      /* Find beginning of next value.  */
      if (mark++ && *mark)
	line = mark;
      else
	line = NULL;
    }

  return 0;
}
Esempio n. 6
0
static gpgme_error_t
parse_notation (gpgme_signature_t sig, gpgme_status_code_t code, char *args)
{
  gpgme_error_t err;
  gpgme_sig_notation_t *lastp = &sig->notations;
  gpgme_sig_notation_t notation = sig->notations;
  char *end = strchr (args, ' ');

  if (end)
    *end = '\0';

  if (code == GPGME_STATUS_NOTATION_NAME || code == GPGME_STATUS_POLICY_URL)
    {
      /* FIXME: We could keep a pointer to the last notation in the list.  */
      while (notation && notation->value)
	{
	  lastp = &notation->next;
	  notation = notation->next;
	}

      if (notation)
	/* There is another notation name without data for the
	   previous one.  The crypto backend misbehaves.  */
	return gpg_error (GPG_ERR_INV_ENGINE);

      err = _gpgme_sig_notation_create (&notation, NULL, 0, NULL, 0, 0);
      if (err)
	return err;

      if (code == GPGME_STATUS_NOTATION_NAME)
	{
	  err = _gpgme_decode_percent_string (args, &notation->name, 0, 0);
	  if (err)
	    {
	      _gpgme_sig_notation_free (notation);
	      return err;
	    }

	  notation->name_len = strlen (notation->name);

	  /* FIXME: For now we fake the human-readable flag.  The
	     critical flag can not be reported as it is not
	     provided.  */
	  notation->flags = GPGME_SIG_NOTATION_HUMAN_READABLE;
	  notation->human_readable = 1;
	}
      else
	{
	  /* This is a policy URL.  */

	  err = _gpgme_decode_percent_string (args, &notation->value, 0, 0);
	  if (err)
	    {
	      _gpgme_sig_notation_free (notation);
	      return err;
	    }

	  notation->value_len = strlen (notation->value);
	}
      *lastp = notation;
    }
  else if (code == GPGME_STATUS_NOTATION_DATA)
    {
      int len = strlen (args) + 1;
      char *dest;

      /* FIXME: We could keep a pointer to the last notation in the list.  */
      while (notation && notation->next)
	{
	  lastp = &notation->next;
	  notation = notation->next;
	}

      if (!notation || !notation->name)
	/* There is notation data without a previous notation
	   name.  The crypto backend misbehaves.  */
	return gpg_error (GPG_ERR_INV_ENGINE);
      
      if (!notation->value)
	{
	  dest = notation->value = malloc (len);
	  if (!dest)
	    return gpg_error_from_errno (errno);
	}
      else
	{
	  int cur_len = strlen (notation->value);
	  dest = realloc (notation->value, len + strlen (notation->value));
	  if (!dest)
	    return gpg_error_from_errno (errno);
	  notation->value = dest;
	  dest += cur_len;
	}
      
      err = _gpgme_decode_percent_string (args, &dest, len, 0);
      if (err)
	return err;

      notation->value_len += strlen (dest);
    }
  else
    return gpg_error (GPG_ERR_INV_ENGINE);
  return 0;
}