Esempio n. 1
0
/* Convert STRING consisting of hex characters into its binary representation
   and store that at BUFFER.  BUFFER needs to be of LENGTH bytes.  The
   function check that the STRING will convert exactly to LENGTH
   bytes. Colons between the hex digits are allowed, if one colon
   has been given a colon is expected very 2 characters. The string
   is delimited by either end of string or a white space character.
   The function returns -1 on error or the length of the parsed
   string.  */
int
hexcolon2bin (const char *string, void *buffer, size_t length)
{
  int i;
  const char *s = string;
  int need_colon = 0;

  for (i=0; i < length; )
    {
      if (i==1 && *s == ':')  /* Skip colons between hex digits.  */
        {
          need_colon = 1;
          s++;
        }
      else if (need_colon && *s == ':')
        s++;
      else if (need_colon)
        return -1;           /* Colon expected. */
      if (!hexdigitp (s) || !hexdigitp (s+1))
        return -1;           /* Invalid hex digits. */
      ((unsigned char*)buffer)[i++] = xtoi_2 (s);
      s += 2;
    }
  if (*s == ':')
    return -1;             /* Trailing colons are not allowed.  */
  if (*s && (!isascii (*s) || !isspace (*s)) )
    return -1;             /* Not followed by Nul or white space.  */
  if (i != length)
    return -1;             /* Not of expected length.  */
  if (*s)
    s++; /* Skip the delimiter. */
  return s - string;
}
Esempio n. 2
0
/* Return a certificate object for the given fingerprint.  STRING is
   expected to be a SHA-1 fingerprint in standard hex notation with or
   without colons.  If no matching certificate is available in the
   cache NULL is returned.  The caller must release a returned
   certificate.  Note that although we are using reference counting
   the caller should not just compare the pointers to check for
   identical certificates. */
ksba_cert_t
get_cert_byhexfpr (const char *string)
{
  unsigned char fpr[20];
  const char *s;
  int i;

  if (strchr (string, ':'))
    {
      for (s=string,i=0; i < 20 && hexdigitp (s) && hexdigitp(s+1);)
        {
          if (s[2] && s[2] != ':')
            break; /* Invalid string. */
          fpr[i++] = xtoi_2 (s);
          s += 2;
          if (i!= 20 && *s == ':')
            s++;
        }
    }
  else
    {
      for (s=string,i=0; i < 20 && hexdigitp (s) && hexdigitp(s+1); s+=2 )
        fpr[i++] = xtoi_2 (s);
    }
  if (i!=20 || *s)
    {
      log_error (_("invalid SHA1 fingerprint string '%s'\n"), string);
      return NULL;
    }

  return get_cert_byfpr (fpr);
}
Esempio n. 3
0
File: misc.c Progetto: FMayzek/gnupg
/* Convert the hex encoded STRING back into binary and store the
   result into the provided buffer RESULT.  The actual size of that
   buffer will be returned.  The caller should provide RESULT of at
   least strlen(STRING)/2 bytes.  There is no error detection, the
   parsing stops at the first non hex character.  With RESULT given as
   NULL, the fucntion does only return the size of the buffer which
   would be needed.  */
size_t
unhexify (unsigned char *result, const char *string)
{
  const char *s;
  size_t n;

  for (s=string,n=0; hexdigitp (s) && hexdigitp(s+1); s += 2)
    {
      if (result)
        result[n] = xtoi_2 (s);
      n++;
    }
  return n;
}
Esempio n. 4
0
/* A simple callback used to return the serialnumber of a card.  */
static gpg_error_t
get_serialno_cb (void *opaque, const char *line)
{
    char **serialno = opaque;
    const char *keyword = line;
    const char *s;
    int keywordlen, n;

    for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
        ;
    while (spacep (line))
        line++;

    if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
    {
        if (*serialno)
            return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */
        for (n=0,s=line; hexdigitp (s); s++, n++)
            ;
        if (!n || (n&1)|| !(spacep (s) || !*s) )
            return gpg_error (GPG_ERR_ASS_PARAMETER);
        *serialno = xtrymalloc (n+1);
        if (!*serialno)
            return out_of_core ();
        memcpy (*serialno, line, n);
        (*serialno)[n] = 0;
    }

    return 0;
}
Esempio n. 5
0
static void
collect_data (char *hexdata, const char *address, unsigned int lineno)
{
  size_t length;
  int is_bi;
  char *s;
  unsigned int value;

  is_bi = (*address && address[1] == 'i');

  if (databuffer.is_bi != is_bi || strcmp (databuffer.address, address))
    flush_data ();
  databuffer.is_bi = is_bi;
  if (strlen (address) >= sizeof databuffer.address)
    die ("address field too long");
  strcpy (databuffer.address, address);

  length = databuffer.count;
  for (s=hexdata; *s; s++ )
    {
      if (ascii_isspace (*s))
        continue;
      if (!hexdigitp (*s))
        {
          err ("invalid hex digit in line %u - line skipped", lineno);
          break;
        }
      value = xtoi_1 (*s) * 16;
      s++;
      if (!hexdigitp (*s))
        {
          err ("invalid hex digit in line %u - line skipped", lineno);
          break;
        }
      value += xtoi_1 (*s);

      if (length >= sizeof (databuffer.data))
        {
          err ("too much data at line %u - can handle only up to % bytes",
               lineno, sizeof (databuffer.data));
          break;
        }
      databuffer.data[length++] = value;
    }
  databuffer.count = length;
}
Esempio n. 6
0
/* Convert STRING consisting of hex characters into its binary
   representation and return it as an allocated buffer. The valid
   length of the buffer is returned at R_LENGTH.  The string is
   delimited by end of string.  The function returns NULL on
   error.  */
static void *
data_from_hex (const char *string, size_t *r_length)
{
  const char *s;
  unsigned char *buffer;
  size_t length;

  buffer = gcry_xmalloc (strlen(string)/2+1);
  length = 0;
  for (s=string; *s; s +=2 )
    {
      if (!hexdigitp (s) || !hexdigitp (s+1))
        die ("error parsing hex string `%s'\n", string);
      ((unsigned char*)buffer)[length++] = xtoi_2 (s);
    }
  *r_length = length;
  return buffer;
}
Esempio n. 7
0
/* Convert STRING consisting of hex characters into its binary
   representation and return it as an allocated buffer. The valid
   length of the buffer is returned at R_LENGTH.  The string is
   delimited by end of string.  The function returns NULL on
   error.  */
static void *
hex2buffer (const char *string, size_t *r_length)
{
  const char *s;
  unsigned char *buffer;
  size_t length;

  buffer = xmalloc (strlen(string)/2+1);
  length = 0;
  for (s=string; *s; s +=2 )
    {
      if (!hexdigitp (s) || !hexdigitp (s+1))
        return NULL;           /* Invalid hex digits. */
      ((unsigned char*)buffer)[length++] = xtoi_2 (s);
    }
  *r_length = length;
  return buffer;
}
/* Convert STRING consisting of hex characters into its binary
 representation and store that at BUFFER.  BUFFER needs to be of
 LENGTH bytes.  The function returns -1 on
 error or the length of the parsed string.  */
int convert_hexstring_to_char (const char *hex_string, size_t length, void *char_string)
{
    int i;
    const char *s = hex_string;
    char_string = malloc(length);
    char *p;
    p = malloc(length);
    for (i=0; i < length; )
    {
        if (!hexdigitp (s) || !hexdigitp (s+1)) return -1;           /* Invalid hex digits. */
        ((unsigned char*)char_string)[i++] = xtoi_2 (s);
        p[i++] = xtoi_2 (s);
        s += 2;
    }
    if (*s && (!isascii (*s) || !isspace (*s)) ) return -1;             /* Not followed by Nul or white space.  */
    if (i != length) return -1;             /* Not of expected length.  */
    if (*s) s++; /* Skip the delimiter. */
    return (int)(s - hex_string);
}
Esempio n. 9
0
/* Convert HEXSTRING consisting of hex characters into string and
   store that at BUFFER.  HEXSTRING is either delimited by end of
   string or a white space character.  The function makes sure that
   the resulting string in BUFFER is terminated by a Nul byte.  Note
   that the retruned string may include embedded Nul bytes; the extra
   Nul byte at the end is used to make sure tha the result can always
   be used as a C-string.

   BUFSIZE is the available length of BUFFER; if the converted result
   plus a possible required extra Nul character does not fit into this
   buffer, the function returns NULL and won't change the existing
   content of BUFFER.  In-place conversion is possible as long as
   BUFFER points to HEXSTRING.

   If BUFFER is NULL and BUFSIZE is 0 the function scans HEXSTRING but
   does not store anything.  This may be used to find the end of
   HEXSTRING.

   On success the function returns a pointer to the next character
   after HEXSTRING (which is either end-of-string or a the next white
   space).  If BUFLEN is not NULL the number of valid vytes in BUFFER
   is stored there (an extra Nul byte is not counted); this will even
   be done if BUFFER has been passed as NULL. */
const char *
hex2str (const char *hexstring, char *buffer, size_t bufsize, size_t *buflen)
{
  const char *s = hexstring;
  int idx, count;
  int need_nul = 0;

  if (buflen)
    *buflen = 0;

  for (s=hexstring, count=0; hexdigitp (s) && hexdigitp (s+1); s += 2, count++)
    ;
  if (*s && (!isascii (*s) || !isspace (*s)) )
    {
      gpg_err_set_errno (EINVAL);
      return NULL;   /* Not followed by Nul or white space.  */
    }
  /* We need to append a nul character.  However we don't want that if
     the hexstring already ends with "00".  */
  need_nul = ((s == hexstring) || !(s[-2] == '0' && s[-1] == '0'));
  if (need_nul)
    count++;

  if (buffer)
    {
      if (count > bufsize)
        {
          gpg_err_set_errno (EINVAL);
          return NULL; /* Too long.  */
        }

      for (s=hexstring, idx=0; hexdigitp (s) && hexdigitp (s+1); s += 2)
        ((unsigned char*)buffer)[idx++] = xtoi_2 (s);
      if (need_nul)
        buffer[idx] = 0;
    }

  if (buflen)
    *buflen = count - need_nul;
  return s;
}
Esempio n. 10
0
/* Convert STRING consisting of hex characters into its binary
   representation and store that at BUFFER.  BUFFER needs to be of
   LENGTH bytes.  The function checks that the STRING will convert
   exactly to LENGTH bytes. The string is delimited by either end of
   string or a white space character.  The function returns -1 on
   error or the length of the parsed string.  */
int
hex2bin (const char *string, void *buffer, size_t length)
{
  int i;
  const char *s = string;

  for (i=0; i < length; )
    {
      if (!hexdigitp (s) || !hexdigitp (s+1))
        return -1;           /* Invalid hex digits. */
      ((unsigned char*)buffer)[i++] = xtoi_2 (s);
      s += 2;
    }
  if (*s && (!isascii (*s) || !isspace (*s)) )
    return -1;             /* Not followed by Nul or white space.  */
  if (i != length)
    return -1;             /* Not of expected length.  */
  if (*s)
    s++; /* Skip the delimiter. */
  return s - string;
}
Esempio n. 11
0
File: misc.c Progetto: FMayzek/gnupg
/****************
 * Remove all %xx escapes; this is done inplace.
 * Returns: New length of the string.
 */
static int
remove_percent_escapes (unsigned char *string)
{
  int n = 0;
  unsigned char *p, *s;

  for (p = s = string; *s; s++)
    {
      if (*s == '%')
        {
          if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
            {
              s++;
              *p = xtoi_2 (s);
              s++;
              p++;
              n++;
            }
          else
            {
              *p++ = *s++;
              if (*s)
                *p++ = *s++;
              if (*s)
                *p++ = *s++;
              if (*s)
                *p = 0;
              return -1;   /* Bad URI. */
            }
        }
      else
        {
          *p++ = *s;
          n++;
        }
    }
  *p = 0;  /* Always keep a string terminator. */
  return n;
}
Esempio n. 12
0
/* Take a 20 byte hexencoded string and put it into the the provided
   20 byte buffer FPR in binary format. */
static int
unhexify_fpr (const char *hexstr, unsigned char *fpr)
{
    const char *s;
    int n;

    for (s=hexstr, n=0; hexdigitp (s); s++, n++)
        ;
    if (*s || (n != 40))
        return 0; /* no fingerprint (invalid or wrong length). */
    for (s=hexstr, n=0; *s; s += 2, n++)
        fpr[n] = xtoi_2 (s);
    return 1; /* okay */
}
Esempio n. 13
0
/* Take the serial number from LINE and return it verbatim in a newly
   allocated string.  We make sure that only hex characters are
   returned. */
static char *
store_serialno (const char *line)
{
    const char *s;
    char *p;

    for (s=line; hexdigitp (s); s++)
        ;
    p = xtrymalloc (s + 1 - line);
    if (p)
    {
        memcpy (p, line, s-line);
        p[s-line] = 0;
    }
    return p;
}
Esempio n. 14
0
/* Create a simple S-expression from the hex string at LINE.  Returns
   a newly allocated buffer with that canonical encoded S-expression
   or NULL in case of an error.  On return the number of characters
   scanned in LINE will be stored at NSCANNED.  This fucntions stops
   converting at the first character not representing a hexdigit. Odd
   numbers of hex digits are allowed; a leading zero is then
   assumed. If no characters have been found, NULL is returned.*/
unsigned char *
make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
{
    size_t n, len;
    const char *s;
    unsigned char *buf;
    unsigned char *p;
    char numbuf[50], *numbufp;
    size_t numbuflen;

    for (n=0, s=line; hexdigitp (s); s++, n++)
        ;
    if (nscanned)
        *nscanned = n;
    if (!n)
        return NULL;
    len = ((n+1) & ~0x01)/2;
    numbufp = smklen (numbuf, sizeof numbuf, len, &numbuflen);
    buf = xtrymalloc (1 + numbuflen + len + 1 + 1);
    if (!buf)
        return NULL;
    buf[0] = '(';
    p = (unsigned char *)stpcpy ((char *)buf+1, numbufp);
    s = line;
    if ((n&1))
    {
        *p++ = xtoi_1 (s);
        s++;
        n--;
    }
    for (; n > 1; n -=2, s += 2)
        *p++ = xtoi_2 (s);
    *p++ = ')';
    *p = 0; /* (Not really neaded.) */

    return buf;
}
Esempio n. 15
0
/* Handle a SENDCERT inquiry. */
static gpg_error_t
inq_certificate (void *opaque, const char *line)
{
  struct inq_certificate_parm_s *parm = opaque;
  int rc;
  const unsigned char *der;
  size_t derlen;
  int issuer_mode = 0;
  ksba_sexp_t ski = NULL;

  if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8]))
    {
      line += 8;
    }
  else if (!strncmp (line, "SENDCERT_SKI", 12) && (line[12]==' ' || !line[12]))
    {
      size_t n;

      /* Send a certificate where a sourceKeyIdentifier is included. */
      line += 12;
      while (*line == ' ')
        line++;
      ski = make_simple_sexp_from_hexstr (line, &n);
      line += n;
      while (*line == ' ')
        line++;
    }
  else if (!strncmp (line, "SENDISSUERCERT", 14)
           && (line[14] == ' ' || !line[14]))
    {
      line += 14;
      issuer_mode = 1;
    }
  else if (!strncmp (line, "ISTRUSTED", 9) && (line[9]==' ' || !line[9]))
    {
      /* The server is asking us whether the certificate is a trusted
         root certificate.  */
      const char *s;
      size_t n;
      char fpr[41];
      struct rootca_flags_s rootca_flags;

      line += 9;
      while (*line == ' ')
        line++;

      for (s=line,n=0; hexdigitp (s); s++, n++)
        ;
      if (*s || n != 40)
        return gpg_error (GPG_ERR_ASS_PARAMETER);
      for (s=line, n=0; n < 40; s++, n++)
        fpr[n] = (*s >= 'a')? (*s & 0xdf): *s;
      fpr[n] = 0;
      
      if (!gpgsm_agent_istrusted (parm->ctrl, NULL, fpr, &rootca_flags))
        rc = assuan_send_data (parm->ctx, "1", 1);
      else
        rc = 0;
      return rc;
    }
  else
    {
      log_error ("unsupported inquiry `%s'\n", line);
      return gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
    }

  if (!*line)
    { /* Send the current certificate. */
      der = ksba_cert_get_image (issuer_mode? parm->issuer_cert : parm->cert,
                                 &derlen);
      if (!der)
        rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
      else
        rc = assuan_send_data (parm->ctx, der, derlen);
    }
  else if (issuer_mode)
    {
      log_error ("sending specific issuer certificate back "
                 "is not yet implemented\n");
      rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
    }
  else 
    { /* Send the given certificate. */
      int err;
      ksba_cert_t cert;


      err = gpgsm_find_cert (line, ski, &cert);
      if (err)
        {
          log_error ("certificate not found: %s\n", gpg_strerror (err));
          rc = gpg_error (GPG_ERR_NOT_FOUND);
        }
      else
        {
          der = ksba_cert_get_image (cert, &derlen);
          if (!der)
            rc = gpg_error (GPG_ERR_INV_CERT_OBJ);
          else
            rc = assuan_send_data (parm->ctx, der, derlen);
          ksba_cert_release (cert);
        }
    }

  xfree (ski);
  return rc; 
}
Esempio n. 16
0
/* helper for the rfc2253 string parser */
static const unsigned char *
parse_dn_part (struct dn_array_s *array, const unsigned char *string)
{
  static struct {
    const char *label;
    const char *oid;
  } label_map[] = {
    /* Warning: When adding new labels, make sure that the buffer
       below we be allocated large enough. */
    {"EMail",        "1.2.840.113549.1.9.1" },
    {"T",            "2.5.4.12" },
    {"GN",           "2.5.4.42" },
    {"SN",           "2.5.4.4" },
    {"NameDistinguisher", "0.2.262.1.10.7.20"},
    {"ADDR",         "2.5.4.16" },
    {"BC",           "2.5.4.15" },
    {"D",            "2.5.4.13" },
    {"PostalCode",   "2.5.4.17" },
    {"Pseudo",       "2.5.4.65" },
    {"SerialNumber", "2.5.4.5" },
    {NULL, NULL}
  };
  const unsigned char *s, *s1;
  size_t n;
  char *p;
  int i;

  /* Parse attributeType */
  for (s = string+1; *s && *s != '='; s++)
    ;
  if (!*s)
    return NULL; /* error */
  n = s - string;
  if (!n)
    return NULL; /* empty key */

  /* We need to allocate a few bytes more due to the possible mapping
     from the shorter OID to the longer label. */
  array->key = p = xtrymalloc (n+10);
  if (!array->key)
    return NULL;
  memcpy (p, string, n);
  p[n] = 0;
  trim_trailing_spaces (p);

  if (digitp (p))
    {
      for (i=0; label_map[i].label; i++ )
        if ( !strcmp (p, label_map[i].oid) )
          {
            strcpy (p, label_map[i].label);
            break;
          }
    }
  string = s + 1;

  if (*string == '#')
    { /* hexstring */
      string++;
      for (s=string; hexdigitp (s); s++)
        s++;
      n = s - string;
      if (!n || (n & 1))
        return NULL; /* Empty or odd number of digits. */
      n /= 2;
      array->value = p = xtrymalloc (n+1);
      if (!p)
        return NULL;
      for (s1=string; n; s1 += 2, n--, p++)
        {
          *(unsigned char *)p = xtoi_2 (s1);
          if (!*p)
            *p = 0x01; /* Better print a wrong value than truncating
                          the string. */
        }
      *p = 0;
   }
  else
    { /* regular v3 quoted string */
      for (n=0, s=string; *s; s++)
        {
          if (*s == '\\')
            { /* pair */
              s++;
              if (*s == ',' || *s == '=' || *s == '+'
                  || *s == '<' || *s == '>' || *s == '#' || *s == ';'
                  || *s == '\\' || *s == '\"' || *s == ' ')
                n++;
              else if (hexdigitp (s) && hexdigitp (s+1))
                {
                  s++;
                  n++;
                }
              else
                return NULL; /* invalid escape sequence */
            }
          else if (*s == '\"')
            return NULL; /* invalid encoding */
          else if (*s == ',' || *s == '=' || *s == '+'
                   || *s == '<' || *s == '>' || *s == ';' )
            break;
          else
            n++;
        }

      array->value = p = xtrymalloc (n+1);
      if (!p)
        return NULL;
      for (s=string; n; s++, n--)
        {
          if (*s == '\\')
            {
              s++;
              if (hexdigitp (s))
                {
                  *(unsigned char *)p++ = xtoi_2 (s);
                  s++;
                }
              else
                *p++ = *s;
            }
          else
            *p++ = *s;
        }
      *p = 0;
    }
  return s;
}
Esempio n. 17
0
/* Ask the gpg-agent for a passphrase and present the user with a
   DESCRIPTION, a PROMPT and optionally with a TRYAGAIN extra text.
   If a CACHEID is not NULL it is used to locate the passphrase in in
   the cache and store it under this ID.  If OPT_CHECK is true
   gpg-agent is asked to apply some checks on the passphrase security.
   If ERRORCODE is not NULL it should point a variable receiving an
   errorcode; this error code might be 0 if the user canceled the
   operation.  The function returns NULL to indicate an error.  */
char *
simple_pwquery (const char *cacheid, 
                const char *tryagain,
                const char *prompt,
                const char *description,
                int opt_check,
                int *errorcode)
{
  int fd = -1;
  int nread;
  char *result = NULL;
  char *pw = NULL;
  char *p;
  int rc, i; 

  rc = agent_open (&fd);
  if (rc)
    goto leave;

  if (!cacheid)
    cacheid = "X";
  if (!tryagain)
    tryagain = "X";
  if (!prompt)
    prompt = "X";
  if (!description)
    description = "X";

  {
    char *line;
    /* We allocate 3 times the needed space so that there is enough
       space for escaping. */
    line = spwq_malloc (15 + 10
                        + 3*strlen (cacheid) + 1
                        + 3*strlen (tryagain) + 1
                        + 3*strlen (prompt) + 1
                        + 3*strlen (description) + 1
                        + 2);
    if (!line)
      {
        rc = SPWQ_OUT_OF_CORE;
        goto leave;
      }
    strcpy (line, "GET_PASSPHRASE ");
    p = line+15;
    if (opt_check)
      p = stpcpy (p, "--check ");
    p = copy_and_escape (p, cacheid);
    *p++ = ' ';
    p = copy_and_escape (p, tryagain);
    *p++ = ' ';
    p = copy_and_escape (p, prompt);
    *p++ = ' ';
    p = copy_and_escape (p, description);
    *p++ = '\n';
    rc = writen (fd, line, p - line);
    spwq_free (line);
    if (rc)
      goto leave;
  }

  /* get response */
  pw = spwq_secure_malloc (500);
  nread = readline (fd, pw, 499);
  if (nread < 0)
    {
      rc = -nread;
      goto leave;
    }
  if (nread < 3)
    {
      rc = SPWQ_PROTOCOL_ERROR;
      goto leave;
    }
      
  if (pw[0] == 'O' && pw[1] == 'K' && pw[2] == ' ') 
    { /* we got a passphrase - convert it back from hex */
      size_t pwlen = 0;
      
      for (i=3; i < nread && hexdigitp (pw+i); i+=2)
        pw[pwlen++] = xtoi_2 (pw+i);
      pw[pwlen] = 0; /* make a C String */
      result = pw;
      pw = NULL;
    }
  else if ((nread > 7 && !memcmp (pw, "ERR 111", 7)
            && (pw[7] == ' ' || pw[7] == '\n') )
           || ((nread > 4 && !memcmp (pw, "ERR ", 4)
                && (strtoul (pw+4, NULL, 0) & 0xffff) == 99)) ) 
    {
      /* 111 is the old Assuan code for canceled which might still
         be in use by old installations. 99 is GPG_ERR_CANCELED as
         used by modern gpg-agents; 0xffff is used to mask out the
         error source.  */
#ifdef SPWQ_USE_LOGGING
      log_info (_("canceled by user\n") );
#endif
      *errorcode = 0; /* Special error code to indicate Cancel. */
    }
  else if (nread > 4 && !memcmp (pw, "ERR ", 4))
    {
      switch ( (strtoul (pw+4, NULL, 0) & 0xffff) )
        {
        case 85: rc = SPWQ_NO_PIN_ENTRY;  break;
        default: rc = SPWQ_GENERAL_ERROR; break;
        }
    }
  else 
    {
#ifdef SPWQ_USE_LOGGING
      log_error (_("problem with the agent\n"));
#endif
      rc = SPWQ_ERR_RESPONSE;
    }
        
 leave:
  if (errorcode)
    *errorcode = rc;
  if (fd != -1)
    close (fd);
  if (pw)
    spwq_secure_free (pw);
  return result;
}
Esempio n. 18
0
/* Read the first PEM certificate from the file FNAME.  If fname is
   NULL the next certificate is read from stdin.  The certificate is
   returned in an alloced buffer whose address will be returned in
   RBUF and its length in RBUFLEN.  */
static gpg_error_t
read_pem_certificate (const char *fname, unsigned char **rbuf, size_t *rbuflen)
{
  FILE *fp;
  int c;
  int pos;
  int value;
  unsigned char *buf;
  size_t bufsize, buflen;
  enum {
    s_init, s_idle, s_lfseen, s_begin,
    s_b64_0, s_b64_1, s_b64_2, s_b64_3,
    s_waitend
  } state = s_init;

  fp = fname? fopen (fname, "r") : stdin;
  if (!fp)
    return gpg_error_from_errno (errno);

  pos = 0;
  value = 0;
  bufsize = 8192;
  buf = xmalloc (bufsize);
  buflen = 0;
  while ((c=getc (fp)) != EOF)
    {
      int escaped_c = 0;

      if (opt.escaped_pem)
        {
          if (c == '%')
            {
              char tmp[2];
              if ((c = getc(fp)) == EOF)
                break;
              tmp[0] = c;
              if ((c = getc(fp)) == EOF)
                break;
              tmp[1] = c;
              if (!hexdigitp (tmp) || !hexdigitp (tmp+1))
                {
                  log_error ("invalid percent escape sequence\n");
                  state = s_idle; /* Force an error. */
                  /* Skip to end of line.  */
                  while ( (c=getc (fp)) != EOF && c != '\n')
                    ;
                  goto ready;
                }
              c = xtoi_2 (tmp);
              escaped_c = 1;
            }
          else if (c == '\n')
            goto ready; /* Ready.  */
        }
      switch (state)
        {
        case s_idle:
          if (c == '\n')
            {
              state = s_lfseen;
              pos = 0;
            }
          break;
        case s_init:
          state = s_lfseen;
        case s_lfseen:
          if (c != "-----BEGIN "[pos])
            state = s_idle;
          else if (pos == 10)
            state = s_begin;
          else
            pos++;
          break;
        case s_begin:
          if (c == '\n')
            state = s_b64_0;
          break;
        case s_b64_0:
        case s_b64_1:
        case s_b64_2:
        case s_b64_3:
          {
            if (buflen >= bufsize)
              {
                bufsize += 8192;
                buf = xrealloc (buf, bufsize);
              }

            if (c == '-')
              state = s_waitend;
            else if ((c = asctobin[c & 0xff]) == 255 )
              ; /* Just skip invalid base64 characters. */
            else if (state == s_b64_0)
              {
                value = c << 2;
                state = s_b64_1;
              }
            else if (state == s_b64_1)
              {
                value |= (c>>4)&3;
                buf[buflen++] = value;
                value = (c<<4)&0xf0;
                state = s_b64_2;
              }
            else if (state == s_b64_2)
              {
                value |= (c>>2)&15;
                buf[buflen++] = value;
                value = (c<<6)&0xc0;
                state = s_b64_3;
              }
            else
              {
Esempio n. 19
0
/* Parse a DN and return an array-ized one.  This is not a validating
   parser and it does not support any old-stylish syntax; gpgme is
   expected to return only rfc2253 compatible strings. */
static const unsigned char *
parse_dn_part (DnPair *array, const unsigned char *string)
{
  const unsigned char *s, *s1;
  size_t n;
  char *p;

  /* parse attributeType */
  for (s = string+1; *s && *s != '='; s++)
    ;
  if (!*s)
    return NULL; /* error */
  n = s - string;
  if (!n)
    return NULL; /* empty key */
  p = (char*)malloc (n+1);
  
  
  memcpy (p, string, n);
  p[n] = 0;
  trim_trailing_spaces ((char*)p);
  // map OIDs to their names:
  for ( unsigned int i = 0 ; i < numOidMaps ; ++i )
    if ( !strcasecmp ((char*)p, oidmap[i].oid) ) {
      free( p );
      p = strdup( oidmap[i].name );
      break;
    }
  array->key = p;
  string = s + 1;

  if (*string == '#')
    { /* hexstring */
      string++;
      for (s=string; hexdigitp (s); s++)
        s++;
      n = s - string;
      if (!n || (n & 1))
        return NULL; /* empty or odd number of digits */
      n /= 2;
      array->value = p = (char*)malloc (n+1);
      
      
      for (s1=string; n; s1 += 2, n--)
        *p++ = xtoi_2 (s1);
      *p = 0;
   }
  else
    { /* regular v3 quoted string */
      for (n=0, s=string; *s; s++)
        {
          if (*s == '\\')
            { /* pair */
              s++;
              if (*s == ',' || *s == '=' || *s == '+'
                  || *s == '<' || *s == '>' || *s == '#' || *s == ';' 
                  || *s == '\\' || *s == '\"' || *s == ' ')
                n++;
              else if (hexdigitp (s) && hexdigitp (s+1))
                {
                  s++;
                  n++;
                }
              else
                return NULL; /* invalid escape sequence */
            }
          else if (*s == '\"')
            return NULL; /* invalid encoding */
          else if (*s == ',' || *s == '=' || *s == '+'
                   || *s == '<' || *s == '>' || *s == '#' || *s == ';' )
            break; 
          else
            n++;
        }

      array->value = p = (char*)malloc (n+1);
      
      
      for (s=string; n; s++, n--)
        {
          if (*s == '\\')
            { 
              s++;
              if (hexdigitp (s))
                {
                  *p++ = xtoi_2 (s);
                  s++;
                }
              else
                *p++ = *s;
            }
          else
            *p++ = *s;
        }
      *p = 0;
    }
  return s;
}
Esempio n. 20
0
/****************
 * Scan the provided buffer and return the S expression in our internal
 * format.  Returns a newly allocated expression.  If erroff is not NULL and
 * a parsing error has occurred, the offset into buffer will be returned.
 * If ARGFLAG is true, the function supports some printf like
 * expressions.
 *  These are:
 *	%m - MPI
 *	%s - string (no autoswitch to secure allocation)
 *	%d - integer stored as string (no autoswitch to secure allocation)
 *      %b - memory buffer; this takes _two_ arguments: an integer with the
 *           length of the buffer and a pointer to the buffer.
 *      %S - Copy an gcry_sexp_t here.  The S-expression needs to be a
 *           regular one, starting with a parenthesis.
 *           (no autoswitch to secure allocation)
 *  all other format elements are currently not defined and return an error.
 *  this includes the "%%" sequence becauce the percent sign is not an
 *  allowed character.
 * FIXME: We should find a way to store the secure-MPIs not in the string
 * but as reference to somewhere - this can help us to save huge amounts
 * of secure memory.  The problem is, that if only one element is secure, all
 * other elements are automagicaly copied to secure memory too, so the most
 * common operation gcry_sexp_cdr_mpi() will always return a secure MPI
 * regardless whether it is needed or not.
 */
static gcry_error_t
vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
	     const char *buffer, size_t length, int argflag,
	     void **arg_list, va_list arg_ptr)
{
  gcry_err_code_t err = 0;
  static const char tokenchars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "0123456789-./_:*+=";
  const char *p;
  size_t n;
  const char *digptr = NULL;
  const char *quoted = NULL;
  const char *tokenp = NULL;
  const char *hexfmt = NULL;
  const char *base64 = NULL;
  const char *disphint = NULL;
  const char *percent = NULL;
  int hexcount = 0;
  int quoted_esc = 0;
  int datalen = 0;
  size_t dummy_erroff;
  struct make_space_ctx c;
  int arg_counter = 0;
  int level = 0;

  if (!erroff)
    erroff = &dummy_erroff;

  /* Depending on whether ARG_LIST is non-zero or not, this macro gives
     us the next argument, either from the variable argument list as
     specified by ARG_PTR or from the argument array ARG_LIST.  */
#define ARG_NEXT(storage, type)                          \
  do                                                     \
    {                                                    \
      if (!arg_list)                                     \
	storage = va_arg (arg_ptr, type);                \
      else                                               \
	storage = *((type *) (arg_list[arg_counter++])); \
    }                                                    \
  while (0)

  /* The MAKE_SPACE macro is used before each store operation to
     ensure that the buffer is large enough.  It requires a global
     context named C and jumps out to the label LEAVE on error! It
     also sets ERROFF using the variables BUFFER and P.  */
#define MAKE_SPACE(n)  do {                                                \
                            gpg_err_code_t _ms_err = make_space (&c, (n)); \
                            if (_ms_err)                                   \
                              {                                            \
                                err = _ms_err;                             \
                                *erroff = p - buffer;                      \
                                goto leave;                                \
                              }                                            \
                       } while (0)

  /* The STORE_LEN macro is used to store the length N at buffer P. */
#define STORE_LEN(p,n) do {						   \
			    DATALEN ashort = (n);			   \
			    memcpy ( (p), &ashort, sizeof(ashort) );	   \
			    (p) += sizeof (ashort);			   \
			} while (0)

  /* We assume that the internal representation takes less memory than
     the provided one.  However, we add space for one extra datalen so
     that the code which does the ST_CLOSE can use MAKE_SPACE */
  c.allocated = length + sizeof(DATALEN);
  if (buffer && length && gcry_is_secure (buffer))
    c.sexp = gcry_malloc_secure (sizeof *c.sexp + c.allocated - 1);
  else
    c.sexp = gcry_malloc (sizeof *c.sexp + c.allocated - 1);
  if (!c.sexp)
    {
      err = gpg_err_code_from_errno (errno);
      *erroff = 0;
      goto leave;
    }
  c.pos = c.sexp->d;

  for (p = buffer, n = length; n; p++, n--)
    {
      if (tokenp && !hexfmt)
	{
	  if (strchr (tokenchars, *p))
	    continue;
	  else
	    {
	      datalen = p - tokenp;
	      MAKE_SPACE (datalen);
	      *c.pos++ = ST_DATA;
	      STORE_LEN (c.pos, datalen);
	      memcpy (c.pos, tokenp, datalen);
	      c.pos += datalen;
	      tokenp = NULL;
	    }
	}

      if (quoted)
	{
	  if (quoted_esc)
	    {
	      switch (*p)
		{
		case 'b': case 't': case 'v': case 'n': case 'f':
		case 'r': case '"': case '\'': case '\\':
		  quoted_esc = 0;
		  break;

		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7':
		  if (!((n > 2)
                        && (p[1] >= '0') && (p[1] <= '7')
                        && (p[2] >= '0') && (p[2] <= '7')))
		    {
		      *erroff = p - buffer;
		      /* Invalid octal value.  */
		      err = GPG_ERR_SEXP_BAD_QUOTATION;
                      goto leave;
		    }
		  p += 2;
		  n -= 2;
		  quoted_esc = 0;
		  break;

		case 'x':
		  if (!((n > 2) && hexdigitp (p+1) && hexdigitp (p+2)))
		    {
		      *erroff = p - buffer;
		      /* Invalid hex value.  */
		      err = GPG_ERR_SEXP_BAD_QUOTATION;
                      goto leave;
		    }
		  p += 2;
		  n -= 2;
		  quoted_esc = 0;
		  break;

		case '\r':
		  /* ignore CR[,LF] */
		  if (n && (p[1] == '\n'))
		    {
		      p++;
		      n--;
		    }
		  quoted_esc = 0;
		  break;

		case '\n':
		  /* ignore LF[,CR] */
		  if (n && (p[1] == '\r'))
		    {
		      p++;
		      n--;
		    }
		  quoted_esc = 0;
		  break;

		default:
		  *erroff = p - buffer;
		  /* Invalid quoted string escape.  */
		  err = GPG_ERR_SEXP_BAD_QUOTATION;
                  goto leave;
		}
	    }
	  else if (*p == '\\')
	    quoted_esc = 1;
	  else if (*p == '\"')
	    {
	      /* Keep it easy - we know that the unquoted string will
		 never be larger. */
	      unsigned char *save;
	      size_t len;

	      quoted++; /* Skip leading quote.  */
	      MAKE_SPACE (p - quoted);
	      *c.pos++ = ST_DATA;
	      save = c.pos;
	      STORE_LEN (c.pos, 0); /* Will be fixed up later.  */
	      len = unquote_string (quoted, p - quoted, c.pos);
	      c.pos += len;
	      STORE_LEN (save, len);
	      quoted = NULL;
	    }
	}
      else if (hexfmt)
	{
	  if (isxdigit (*p))
	    hexcount++;
	  else if (*p == '#')
	    {
	      if ((hexcount & 1))
		{
		  *erroff = p - buffer;
		  err = GPG_ERR_SEXP_ODD_HEX_NUMBERS;
                  goto leave;
		}

	      datalen = hexcount / 2;
	      MAKE_SPACE (datalen);
	      *c.pos++ = ST_DATA;
	      STORE_LEN (c.pos, datalen);
	      for (hexfmt++; hexfmt < p; hexfmt++)
		{
                  int tmpc;

		  if (whitespacep (hexfmt))
		    continue;
		  tmpc = hextonibble (*(const unsigned char*)hexfmt);
                  for (hexfmt++; hexfmt < p && whitespacep (hexfmt); hexfmt++)
		    ;
                  if (hexfmt < p)
                    {
                      tmpc *= 16;
                      tmpc += hextonibble (*(const unsigned char*)hexfmt);
                    }
                  *c.pos++ = tmpc;
		}
	      hexfmt = NULL;
	    }
	  else if (!whitespacep (p))
	    {
	      *erroff = p - buffer;
	      err = GPG_ERR_SEXP_BAD_HEX_CHAR;
              goto leave;
	    }
	}
      else if (base64)
	{
	  if (*p == '|')
	    base64 = NULL;
	}
      else if (digptr)
	{
	  if (digitp (p))
	    ;
	  else if (*p == ':')
	    {
	      datalen = atoi (digptr); /* FIXME: check for overflow.  */
	      digptr = NULL;
	      if (datalen > n - 1)
		{
		  *erroff = p - buffer;
		  /* Buffer too short.  */
		  err = GPG_ERR_SEXP_STRING_TOO_LONG;
                  goto leave;
		}
	      /* Make a new list entry.  */
	      MAKE_SPACE (datalen);
	      *c.pos++ = ST_DATA;
	      STORE_LEN (c.pos, datalen);
	      memcpy (c.pos, p + 1, datalen);
	      c.pos += datalen;
	      n -= datalen;
	      p += datalen;
	    }
	  else if (*p == '\"')
	    {
	      digptr = NULL; /* We ignore the optional length.  */
	      quoted = p;
	      quoted_esc = 0;
	    }
	  else if (*p == '#')
	    {
	      digptr = NULL; /* We ignore the optional length.  */
	      hexfmt = p;
	      hexcount = 0;
	    }
	  else if (*p == '|')
	    {
	      digptr = NULL; /* We ignore the optional length.  */
	      base64 = p;
	    }
	  else
	    {
	      *erroff = p - buffer;
	      err = GPG_ERR_SEXP_INV_LEN_SPEC;
              goto leave;
	    }
	}
      else if (percent)
	{
	  if (*p == 'm' || *p == 'M')
	    {
	      /* Insert an MPI.  */
	      gcry_mpi_t m;
	      size_t nm = 0;
              int mpifmt = *p == 'm'? GCRYMPI_FMT_STD: GCRYMPI_FMT_USG;

	      ARG_NEXT (m, gcry_mpi_t);

              if (gcry_mpi_get_flag (m, GCRYMPI_FLAG_OPAQUE))
                {
                  void *mp;
                  unsigned int nbits;

                  mp = gcry_mpi_get_opaque (m, &nbits);
                  nm = (nbits+7)/8;
                  if (mp && nm)
                    {
                      MAKE_SPACE (nm);
                      if (!gcry_is_secure (c.sexp->d)
                          && gcry_mpi_get_flag (m, GCRYMPI_FLAG_SECURE))
                        {
                          /* We have to switch to secure allocation.  */
                          gcry_sexp_t newsexp;
                          byte *newhead;

                          newsexp = gcry_malloc_secure (sizeof *newsexp
                                                        + c.allocated - 1);
                          if (!newsexp)
                            {
                              err = gpg_err_code_from_errno (errno);
                              goto leave;
                            }
                          newhead = newsexp->d;
                          memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
                          c.pos = newhead + (c.pos - c.sexp->d);
                          gcry_free (c.sexp);
                          c.sexp = newsexp;
                        }

                      *c.pos++ = ST_DATA;
                      STORE_LEN (c.pos, nm);
                      memcpy (c.pos, mp, nm);
                      c.pos += nm;
                    }
                }
              else
                {
                  if (gcry_mpi_print (mpifmt, NULL, 0, &nm, m))
                    BUG ();

                  MAKE_SPACE (nm);
                  if (!gcry_is_secure (c.sexp->d)
                      && gcry_mpi_get_flag ( m, GCRYMPI_FLAG_SECURE))
                    {
                      /* We have to switch to secure allocation.  */
                      gcry_sexp_t newsexp;
                      byte *newhead;

                      newsexp = gcry_malloc_secure (sizeof *newsexp
                                                    + c.allocated - 1);
                      if (!newsexp)
                        {
                          err = gpg_err_code_from_errno (errno);
                          goto leave;
                        }
                      newhead = newsexp->d;
                      memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
                      c.pos = newhead + (c.pos - c.sexp->d);
                      gcry_free (c.sexp);
                      c.sexp = newsexp;
                    }

                  *c.pos++ = ST_DATA;
                  STORE_LEN (c.pos, nm);
                  if (gcry_mpi_print (mpifmt, c.pos, nm, &nm, m))
                    BUG ();
                  c.pos += nm;
                }
	    }
	  else if (*p == 's')
	    {
	      /* Insert an string.  */
	      const char *astr;
	      size_t alen;

	      ARG_NEXT (astr, const char *);
	      alen = strlen (astr);

	      MAKE_SPACE (alen);
	      *c.pos++ = ST_DATA;
	      STORE_LEN (c.pos, alen);
	      memcpy (c.pos, astr, alen);
	      c.pos += alen;
	    }
	  else if (*p == 'b')
	    {
	      /* Insert a memory buffer.  */
	      const char *astr;
	      int alen;

	      ARG_NEXT (alen, int);
	      ARG_NEXT (astr, const char *);

	      MAKE_SPACE (alen);
	      if (alen
                  && !gcry_is_secure (c.sexp->d)
		  && gcry_is_secure (astr))
              {
		  /* We have to switch to secure allocation.  */
		  gcry_sexp_t newsexp;
		  byte *newhead;

		  newsexp = gcry_malloc_secure (sizeof *newsexp
                                                + c.allocated - 1);
                  if (!newsexp)
                    {
                      err = gpg_err_code_from_errno (errno);
                      goto leave;
                    }
		  newhead = newsexp->d;
		  memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
		  c.pos = newhead + (c.pos - c.sexp->d);
		  gcry_free (c.sexp);
		  c.sexp = newsexp;
		}

	      *c.pos++ = ST_DATA;
	      STORE_LEN (c.pos, alen);
	      memcpy (c.pos, astr, alen);
	      c.pos += alen;
	    }
	  else if (*p == 'd')
	    {
	      /* Insert an integer as string.  */
	      int aint;
	      size_t alen;
	      char buf[35];

	      ARG_NEXT (aint, int);
	      sprintf (buf, "%d", aint);
	      alen = strlen (buf);
	      MAKE_SPACE (alen);
	      *c.pos++ = ST_DATA;
	      STORE_LEN (c.pos, alen);
	      memcpy (c.pos, buf, alen);
	      c.pos += alen;
	    }
	  else if (*p == 'u')
	    {
	      /* Insert an unsigned integer as string.  */
	      unsigned int aint;
	      size_t alen;
	      char buf[35];

	      ARG_NEXT (aint, unsigned int);
	      sprintf (buf, "%u", aint);
	      alen = strlen (buf);
	      MAKE_SPACE (alen);
	      *c.pos++ = ST_DATA;
	      STORE_LEN (c.pos, alen);
	      memcpy (c.pos, buf, alen);
	      c.pos += alen;
	    }
	  else if (*p == 'S')
	    {
	      /* Insert a gcry_sexp_t.  */
	      gcry_sexp_t asexp;
	      size_t alen, aoff;

	      ARG_NEXT (asexp, gcry_sexp_t);
              alen = get_internal_buffer (asexp, &aoff);
              if (alen)
                {
                  MAKE_SPACE (alen);
                  memcpy (c.pos, asexp->d + aoff, alen);
                  c.pos += alen;
                }
	    }
	  else
	    {
	      *erroff = p - buffer;
	      /* Invalid format specifier.  */
	      err = GPG_ERR_SEXP_INV_LEN_SPEC;
              goto leave;
	    }
	  percent = NULL;
	}
      else if (*p == '(')
	{
	  if (disphint)
	    {
	      *erroff = p - buffer;
	      /* Open display hint.  */
	      err = GPG_ERR_SEXP_UNMATCHED_DH;
              goto leave;
	    }
	  MAKE_SPACE (0);
	  *c.pos++ = ST_OPEN;
	  level++;
	}
      else if (*p == ')')
	{
	  /* Walk up.  */
	  if (disphint)
	    {
	      *erroff = p - buffer;
	      /* Open display hint.  */
	      err = GPG_ERR_SEXP_UNMATCHED_DH;
              goto leave;
	    }
	  MAKE_SPACE (0);
	  *c.pos++ = ST_CLOSE;
	  level--;
	}
      else if (*p == '\"')
	{
	  quoted = p;
	  quoted_esc = 0;
	}
      else if (*p == '#')
	{
	  hexfmt = p;
	  hexcount = 0;
	}
      else if (*p == '|')
	base64 = p;
      else if (*p == '[')
	{
	  if (disphint)
	    {
	      *erroff = p - buffer;
	      /* Open display hint.  */
	      err = GPG_ERR_SEXP_NESTED_DH;
              goto leave;
	    }
	  disphint = p;
	}
      else if (*p == ']')
	{
	  if (!disphint)
	    {
	      *erroff = p - buffer;
	      /* Open display hint.  */
	      err = GPG_ERR_SEXP_UNMATCHED_DH;
              goto leave;
	    }
	  disphint = NULL;
	}
      else if (digitp (p))
	{
	  if (*p == '0')
	    {
	      /* A length may not begin with zero.  */
	      *erroff = p - buffer;
	      err = GPG_ERR_SEXP_ZERO_PREFIX;
              goto leave;
	    }
	  digptr = p;
	}
      else if (strchr (tokenchars, *p))
	tokenp = p;
      else if (whitespacep (p))
	;
      else if (*p == '{')
	{
	  /* fixme: handle rescanning: we can do this by saving our
	     current state and start over at p+1 -- Hmmm. At this
	     point here we are in a well defined state, so we don't
	     need to save it.  Great.  */
	  *erroff = p - buffer;
	  err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
          goto leave;
	}
      else if (strchr ("&\\", *p))
	{
	  /* Reserved punctuation.  */
	  *erroff = p - buffer;
	  err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
          goto leave;
	}
      else if (argflag && (*p == '%'))
	percent = p;
      else
	{
	  /* Bad or unavailable.  */
	  *erroff = p - buffer;
	  err = GPG_ERR_SEXP_BAD_CHARACTER;
          goto leave;
	}
    }
  MAKE_SPACE (0);
  *c.pos++ = ST_STOP;

  if (level && !err)
    err = GPG_ERR_SEXP_UNMATCHED_PAREN;

 leave:
  if (err)
    {
      /* Error -> deallocate.  */
      if (c.sexp)
        {
          /* Extra paranoid wipe on error. */
          if (gcry_is_secure (c.sexp))
            wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1);
          gcry_free (c.sexp);
        }
      /* This might be expected by existing code...  */
      *retsexp = NULL;
    }
  else
    *retsexp = normalize (c.sexp);

  return gcry_error (err);
#undef MAKE_SPACE
#undef STORE_LEN
}
Esempio n. 21
0
/* Unquote STRING of LENGTH and store it into BUF.  The surrounding
   quotes are must already be removed from STRING.  We assume that the
   quoted string is syntacillay correct.  */
static size_t
unquote_string (const char *string, size_t length, unsigned char *buf)
{
  int esc = 0;
  const unsigned char *s = (const unsigned char*)string;
  unsigned char *d = buf;
  size_t n = length;

  for (; n; n--, s++)
    {
      if (esc)
        {
          switch (*s)
            {
            case 'b':  *d++ = '\b'; break;
            case 't':  *d++ = '\t'; break;
            case 'v':  *d++ = '\v'; break;
            case 'n':  *d++ = '\n'; break;
            case 'f':  *d++ = '\f'; break;
            case 'r':  *d++ = '\r'; break;
            case '"':  *d++ = '\"'; break;
            case '\'': *d++ = '\''; break;
            case '\\': *d++ = '\\'; break;

            case '\r':  /* ignore CR[,LF] */
              if (n>1 && s[1] == '\n')
                {
                  s++; n--;
                }
              break;

            case '\n':  /* ignore LF[,CR] */
              if (n>1 && s[1] == '\r')
                {
                  s++; n--;
                }
              break;

            case 'x': /* hex value */
              if (n>2 && hexdigitp (s+1) && hexdigitp (s+2))
                {
                  s++; n--;
                  *d++ = xtoi_2 (s);
                  s++; n--;
                }
              break;

            default:
              if (n>2 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
                {
                  *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
                  s += 2;
                  n -= 2;
                }
              break;
	    }
          esc = 0;
        }
      else if( *s == '\\' )
        esc = 1;
      else
        *d++ = *s;
    }

  return d - buf;
}
Esempio n. 22
0
static void
parse_line_sniffusb (char *line, unsigned int lineno)
{
  char *p;

  if (debug)
    printf ("line[%u] ='%s'\n", lineno, line);

  p = strtok (line, " \t");
  if (!p)
    return;
  p = strtok (NULL, " \t");
  if (!p)
    return;
  p = strtok (NULL, " \t");
  if (!p)
    return;

  if (hexdigitp (p[0]) && hexdigitp (p[1])
      && hexdigitp (p[2]) && hexdigitp (p[3])
      && p[4] == ':' && !p[5])
    {
      size_t length;
      unsigned int value;

      length = databuffer.count;
      while ((p=strtok (NULL, " \t")))
        {
          if (!hexdigitp (p[0]) || !hexdigitp (p[1]))
            {
              err ("invalid hex digit in line %u (%s)", lineno,p);
              break;
            }
          value = xtoi_1 (p[0]) * 16 + xtoi_1 (p[1]);

          if (length >= sizeof (databuffer.data))
            {
              err ("too much data at line %u - can handle only up to % bytes",
                   lineno, sizeof (databuffer.data));
              break;
            }
          databuffer.data[length++] = value;
        }
      databuffer.count = length;

    }
  else if (!strcmp (p, "TransferFlags"))
    {
      flush_data ();

      *databuffer.address = 0;
      while ((p=strtok (NULL, " \t(,)")))
        {
          if (!strcmp (p, "USBD_TRANSFER_DIRECTION_IN"))
            {
              databuffer.is_bi = 1;
              break;
            }
          else if (!strcmp (p, "USBD_TRANSFER_DIRECTION_OUT"))
            {
              databuffer.is_bi = 0;
              break;
            }
        }
    }

}
Esempio n. 23
0
void
import_ownertrust (ctrl_t ctrl, const char *fname )
{
    estream_t fp;
    int is_stdin=0;
    char line[256];
    char *p;
    size_t n, fprlen;
    unsigned int otrust;
    byte fpr[MAX_FINGERPRINT_LEN];
    int any = 0;
    int rc;

    init_trustdb (ctrl, 0);
    if( iobuf_is_pipe_filename (fname) ) {
	fp = es_stdin;
	fname = "[stdin]";
	is_stdin = 1;
    }
    else if( !(fp = es_fopen( fname, "r" )) ) {
	log_error ( _("can't open '%s': %s\n"), fname, strerror(errno) );
	return;
    }

    if (is_secured_file (es_fileno (fp)))
      {
        es_fclose (fp);
        gpg_err_set_errno (EPERM);
	log_error (_("can't open '%s': %s\n"), fname, strerror(errno) );
	return;
      }

    while (es_fgets (line, DIM(line)-1, fp)) {
	TRUSTREC rec;

	if( !*line || *line == '#' )
	    continue;
	n = strlen(line);
	if( line[n-1] != '\n' ) {
	    log_error (_("error in '%s': %s\n"), fname, _("line too long") );
	    /* ... or last line does not have a LF */
	    break; /* can't continue */
	}
	for(p = line; *p && *p != ':' ; p++ )
	    if( !hexdigitp(p) )
		break;
	if( *p != ':' ) {
	    log_error (_("error in '%s': %s\n"), fname, _("colon missing") );
	    continue;
	}
	fprlen = p - line;
	if( fprlen != 32 && fprlen != 40 && fprlen != 64) {
	    log_error (_("error in '%s': %s\n"),
                       fname, _("invalid fingerprint") );
	    continue;
	}
	if( sscanf(p, ":%u:", &otrust ) != 1 ) {
	    log_error (_("error in '%s': %s\n"),
                       fname, _("ownertrust value missing"));
	    continue;
	}
	if( !otrust )
	    continue; /* no otrust defined - no need to update or insert */
	/* Convert the ascii fingerprint to binary */
	for(p=line, fprlen=0;
            fprlen < MAX_FINGERPRINT_LEN && *p != ':';
            p += 2 )
          fpr[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]);
	while (fprlen < MAX_FINGERPRINT_LEN)
	    fpr[fprlen++] = 0;

	rc = tdbio_search_trust_byfpr (fpr, &rec);
	if( !rc ) { /* found: update */
	    if (rec.r.trust.ownertrust != otrust)
              {
                if (!opt.quiet)
                  {
                    if( rec.r.trust.ownertrust )
                      log_info("changing ownertrust from %u to %u\n",
                               rec.r.trust.ownertrust, otrust );
                    else
                      log_info("setting ownertrust to %u\n", otrust );
                  }
                rec.r.trust.ownertrust = otrust;
                write_record (ctrl, &rec);
                any = 1;
              }
	}
	else if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND) { /* insert */
            if (!opt.quiet)
              log_info("inserting ownertrust of %u\n", otrust );
            memset (&rec, 0, sizeof rec);
            rec.recnum = tdbio_new_recnum (ctrl);
            rec.rectype = RECTYPE_TRUST;
            memcpy (rec.r.trust.fingerprint, fpr, 20);
            rec.r.trust.ownertrust = otrust;
            write_record (ctrl, &rec);
            any = 1;
	}
	else /* error */
	    log_error (_("error finding trust record in '%s': %s\n"),
                       fname, gpg_strerror (rc));
    }
    if (es_ferror (fp))
	log_error ( _("read error in '%s': %s\n"), fname, strerror(errno) );
    if (!is_stdin)
	es_fclose (fp);

    if (any)
      {
        revalidation_mark (ctrl);
        rc = tdbio_sync ();
        if (rc)
          log_error (_("trustdb: sync failed: %s\n"), gpg_strerror (rc) );
      }

}