Пример #1
0
const char *
_gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
{
  const char *result = NULL;
  gcry_pk_spec_t *spec;
  gcry_sexp_t keyparms = NULL;

  if (r_nbits)
    *r_nbits = 0;

  if (key)
    {
      iterator = 0;

      if (spec_from_sexp (key, 0, &spec, &keyparms))
        return NULL;
    }
  else
    {
      spec = spec_from_name ("ecc");
      if (!spec)
        return NULL;
    }

  if (spec->get_curve)
    result = spec->get_curve (keyparms, iterator, r_nbits);

  sexp_release (keyparms);
  return result;
}
Пример #2
0
/*
  Create a public key pair and return it in r_key.
  How the key is created depends on s_parms:
  (genkey
   (algo
     (parameter_name_1 ....)
      ....
     (parameter_name_n ....)
  ))
  The key is returned in a format depending on the
  algorithm. Both, private and secret keys are returned
  and optionally some additional informatin.
  For elgamal we return this structure:
  (key-data
   (public-key
     (elg
 	(p <mpi>)
 	(g <mpi>)
 	(y <mpi>)
     )
   )
   (private-key
     (elg
 	(p <mpi>)
 	(g <mpi>)
 	(y <mpi>)
 	(x <mpi>)
     )
   )
   (misc-key-info
      (pm1-factors n1 n2 ... nn)
   ))
 */
gcry_err_code_t
_gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
{
  gcry_pk_spec_t *spec = NULL;
  gcry_sexp_t list = NULL;
  gcry_sexp_t l2 = NULL;
  char *name = NULL;
  gcry_err_code_t rc;

  *r_key = NULL;

  list = sexp_find_token (s_parms, "genkey", 0);
  if (!list)
    {
      rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
      goto leave;
    }

  l2 = sexp_cadr (list);
  sexp_release (list);
  list = l2;
  l2 = NULL;
  if (! list)
    {
      rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
      goto leave;
    }

  name = _gcry_sexp_nth_string (list, 0);
  if (!name)
    {
      rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
      goto leave;
    }

  spec = spec_from_name (name);
  xfree (name);
  name = NULL;
  if (!spec)
    {
      rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
      goto leave;
    }

  if (spec->generate)
    rc = spec->generate (list, r_key);
  else
    rc = GPG_ERR_NOT_IMPLEMENTED;

 leave:
  sexp_release (list);
  xfree (name);
  sexp_release (l2);

  return rc;
}
Пример #3
0
/*
 * Map a string to the pubkey algo
 */
int
_gcry_pk_map_name (const char *string)
{
  gcry_pk_spec_t *spec;

  if (!string)
    return 0;
  spec = spec_from_name (string);
  if (!spec)
    return 0;
  if (spec->flags.disabled)
    return 0;
  return spec->algo;
}
Пример #4
0
/* Given the s-expression SEXP with the first element be either
 * "private-key" or "public-key" return the spec structure for it.  We
 * look through the list to find a list beginning with "private-key"
 * or "public-key" - the first one found is used.  If WANT_PRIVATE is
 * set the function will only succeed if a private key has been given.
 * On success the spec is stored at R_SPEC.  On error NULL is stored
 * at R_SPEC and an error code returned.  If R_PARMS is not NULL and
 * the fucntion returns success, the parameter list below
 * "private-key" or "public-key" is stored there and the caller must
 * call gcry_sexp_release on it.
 */
static gcry_err_code_t
spec_from_sexp (gcry_sexp_t sexp, int want_private,
                gcry_pk_spec_t **r_spec, gcry_sexp_t *r_parms)
{
  gcry_sexp_t list, l2;
  char *name;
  gcry_pk_spec_t *spec;

  *r_spec = NULL;
  if (r_parms)
    *r_parms = NULL;

  /* Check that the first element is valid.  If we are looking for a
     public key but a private key was supplied, we allow the use of
     the private key anyway.  The rationale for this is that the
     private key is a superset of the public key.  */
  list = gcry_sexp_find_token (sexp,
                               want_private? "private-key":"public-key", 0);
  if (!list && !want_private)
    list = gcry_sexp_find_token (sexp, "private-key", 0);
  if (!list)
    return GPG_ERR_INV_OBJ; /* Does not contain a key object.  */

  l2 = gcry_sexp_cadr (list);
  gcry_sexp_release (list);
  list = l2;
  name = _gcry_sexp_nth_string (list, 0);
  if (!name)
    {
      gcry_sexp_release ( list );
      return GPG_ERR_INV_OBJ;      /* Invalid structure of object. */
    }
  spec = spec_from_name (name);
  gcry_free (name);
  if (!spec)
    {
      gcry_sexp_release (list);
      return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
    }
  *r_spec = spec;
  if (r_parms)
    *r_parms = list;
  else
    gcry_sexp_release (list);
  return 0;
}
Пример #5
0
gcry_sexp_t
_gcry_pk_get_param (int algo, const char *name)
{
  gcry_sexp_t result = NULL;
  gcry_pk_spec_t *spec = NULL;

  algo = map_algo (algo);

  if (algo != GCRY_PK_ECC)
    return NULL;

  spec = spec_from_name ("ecc");
  if (spec)
    {
      if (spec && spec->get_curve_param)
        result = spec->get_curve_param (name);
    }
  return result;
}
Пример #6
0
/* Map STRING to the cipher algorithm identifier.  Returns the
   algorithm ID of the cipher for the given name or 0 if the name is
   not known.  It is valid to pass NULL for STRING which results in a
   return value of 0. */
int
_gcry_cipher_map_name (const char *string)
{
  gcry_cipher_spec_t *spec;

  if (!string)
    return 0;

  /* If the string starts with a digit (optionally prefixed with
     either "OID." or "oid."), we first look into our table of ASN.1
     object identifiers to figure out the algorithm */

  spec = search_oid (string, NULL);
  if (spec)
    return spec->algo;

  spec = spec_from_name (string);
  if (spec)
    return spec->algo;

  return 0;
}
Пример #7
0
/* Return the so called KEYGRIP which is the SHA-1 hash of the public
   key parameters expressed in a way depending on the algorithm.

   ARRAY must either be 20 bytes long or NULL; in the latter case a
   newly allocated array of that size is returned, otherwise ARRAY or
   NULL is returned to indicate an error which is most likely an
   unknown algorithm.  The function accepts public or secret keys. */
unsigned char *
_gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
{
  gcry_sexp_t list = NULL;
  gcry_sexp_t l2 = NULL;
  gcry_pk_spec_t *spec = NULL;
  const char *s;
  char *name = NULL;
  int idx;
  const char *elems;
  gcry_md_hd_t md = NULL;
  int okay = 0;

  /* Check that the first element is valid. */
  list = sexp_find_token (key, "public-key", 0);
  if (! list)
    list = sexp_find_token (key, "private-key", 0);
  if (! list)
    list = sexp_find_token (key, "protected-private-key", 0);
  if (! list)
    list = sexp_find_token (key, "shadowed-private-key", 0);
  if (! list)
    return NULL; /* No public- or private-key object. */

  l2 = sexp_cadr (list);
  sexp_release (list);
  list = l2;
  l2 = NULL;

  name = _gcry_sexp_nth_string (list, 0);
  if (!name)
    goto fail; /* Invalid structure of object. */

  spec = spec_from_name (name);
  if (!spec)
    goto fail; /* Unknown algorithm.  */

  elems = spec->elements_grip;
  if (!elems)
    goto fail; /* No grip parameter.  */

  if (_gcry_md_open (&md, GCRY_MD_SHA1, 0))
    goto fail;

  if (spec->comp_keygrip)
    {
      /* Module specific method to compute a keygrip.  */
      if (spec->comp_keygrip (md, list))
        goto fail;
    }
  else
    {
      /* Generic method to compute a keygrip.  */
      for (idx = 0, s = elems; *s; s++, idx++)
        {
          const char *data;
          size_t datalen;
          char buf[30];

          l2 = sexp_find_token (list, s, 1);
          if (! l2)
            goto fail;
          data = sexp_nth_data (l2, 1, &datalen);
          if (! data)
            goto fail;

          _snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
          _gcry_md_write (md, buf, strlen (buf));
          _gcry_md_write (md, data, datalen);
          sexp_release (l2);
          l2 = NULL;
          _gcry_md_write (md, ")", 1);
        }
    }

  if (!array)
    {
      array = xtrymalloc (20);
      if (! array)
        goto fail;
    }

  memcpy (array, _gcry_md_read (md, GCRY_MD_SHA1), 20);
  okay = 1;

 fail:
  xfree (name);
  sexp_release (l2);
  _gcry_md_close (md);
  sexp_release (list);
  return okay? array : NULL;
}