示例#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
/*
   Get the number of nbits from the public key.

   Hmmm: Should we have really this function or is it better to have a
   more general function to retrieve different properties of the key?  */
unsigned int
_gcry_pk_get_nbits (gcry_sexp_t key)
{
  gcry_pk_spec_t *spec;
  gcry_sexp_t parms;
  unsigned int nbits;

  /* Parsing KEY might be considered too much overhead.  For example
     for RSA we would only need to look at P and stop parsing right
     away.  However, with ECC things are more complicate in that only
     a curve name might be specified.  Thus we need to tear the sexp
     apart. */

  if (spec_from_sexp (key, 0, &spec, &parms))
    return 0; /* Error - 0 is a suitable indication for that.  */

  nbits = spec->get_nbits (parms);
  sexp_release (parms);
  return nbits;
}
示例#3
0
/*
   Test a key.

   This may be used either for a public or a secret key to see whether
   the internal structure is okay.

   Returns: 0 or an errorcode.

   NOTE: We currently support only secret key checking. */
gcry_err_code_t
_gcry_pk_testkey (gcry_sexp_t s_key)
{
  gcry_err_code_t rc;
  gcry_pk_spec_t *spec;
  gcry_sexp_t keyparms;

  rc = spec_from_sexp (s_key, 1, &spec, &keyparms);
  if (rc)
    goto leave;

  if (spec->check_secret_key)
    rc = spec->check_secret_key (keyparms);
  else
    rc = GPG_ERR_NOT_IMPLEMENTED;

 leave:
  sexp_release (keyparms);
  return rc;
}
示例#4
0
/*
   Verify a signature.

   Caller has to supply the public key pkey, the signature sig and his
   hashvalue data.  Public key has to be a standard public key given
   as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
   must be an S-Exp like the one in sign too.  */
gcry_err_code_t
_gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
{
  gcry_err_code_t rc;
  gcry_pk_spec_t *spec;
  gcry_sexp_t keyparms;

  rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
  if (rc)
    goto leave;

  if (spec->verify)
    rc = spec->verify (s_sig, s_hash, keyparms);
  else
    rc = GPG_ERR_NOT_IMPLEMENTED;

 leave:
  sexp_release (keyparms);
  return rc;
}
示例#5
0
/*
   Create a signature.

   Caller has to provide a secret key as the SEXP skey and data
   expressed as a SEXP list hash with only one element which should
   instantly be available as a MPI. Alternatively the structure given
   below may be used for S_HASH, it provides the abiliy to pass flags
   to the operation; the flags defined by now are "pkcs1" which does
   PKCS#1 block type 1 style padding and "pss" for PSS encoding.

   Returns: 0 or an errorcode.
            In case of 0 the function returns a new SEXP with the
            signature value; the structure of this signature depends on the
            other arguments but is always suitable to be passed to
            gcry_pk_verify

   s_hash = See comment for _gcry-pk_util_data_to_mpi

   s_skey = <key-as-defined-in-sexp_to_key>
   r_sig  = (sig-val
              (<algo>
                (<param_name1> <mpi>)
                ...
                (<param_namen> <mpi>))
             [(hash algo)])

  Note that (hash algo) in R_SIG is not used.
*/
gcry_err_code_t
_gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
{
  gcry_err_code_t rc;
  gcry_pk_spec_t *spec;
  gcry_sexp_t keyparms;

  *r_sig = NULL;

  rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
  if (rc)
    goto leave;

  if (spec->sign)
    rc = spec->sign (r_sig, s_hash, keyparms);
  else
    rc = GPG_ERR_NOT_IMPLEMENTED;

 leave:
  sexp_release (keyparms);
  return rc;
}
示例#6
0
/*
   Do a PK decrypt operation

   Caller has to provide a secret key as the SEXP skey and data in a
   format as created by gcry_pk_encrypt.  For historic reasons the
   function returns simply an MPI as an S-expression part; this is
   deprecated and the new method should be used which returns a real
   S-expressionl this is selected by adding at least an empty flags
   list to S_DATA.

   Returns: 0 or an errorcode.

   s_data = (enc-val
              [(flags [raw, pkcs1, oaep])]
              (<algo>
                (<param_name1> <mpi>)
                ...
                (<param_namen> <mpi>)
              ))
   s_skey = <key-as-defined-in-sexp_to_key>
   r_plain= Either an incomplete S-expression without the parentheses
            or if the flags list is used (even if empty) a real S-expression:
            (value PLAIN).  In raw mode (or no flags given) the returned value
            is to be interpreted as a signed MPI, thus it may have an extra
            leading zero octet even if not included in the original data.
            With pkcs1 or oaep decoding enabled the returned value is a
            verbatim octet string.
 */
gcry_err_code_t
_gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
{
  gcry_err_code_t rc;
  gcry_pk_spec_t *spec;
  gcry_sexp_t keyparms;

  *r_plain = NULL;

  rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
  if (rc)
    goto leave;

  if (spec->decrypt)
    rc = spec->decrypt (r_plain, s_data, keyparms);
  else
    rc = GPG_ERR_NOT_IMPLEMENTED;

 leave:
  sexp_release (keyparms);
  return rc;
}
示例#7
0
/*
   Do a PK encrypt operation

   Caller has to provide a public key as the SEXP pkey and data as a
   SEXP with just one MPI in it. Alternatively S_DATA might be a
   complex S-Expression, similar to the one used for signature
   verification.  This provides a flag which allows to handle PKCS#1
   block type 2 padding.  The function returns a sexp which may be
   passed to to pk_decrypt.

   Returns: 0 or an errorcode.

   s_data = See comment for _gcry_pk_util_data_to_mpi
   s_pkey = <key-as-defined-in-sexp_to_key>
   r_ciph = (enc-val
               (<algo>
                 (<param_name1> <mpi>)
                 ...
                 (<param_namen> <mpi>)
               ))

*/
gcry_error_t
gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
{
  gcry_err_code_t rc;
  gcry_pk_spec_t *spec;
  gcry_sexp_t keyparms;

  *r_ciph = NULL;

  rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
  if (rc)
    goto leave;

  if (spec->encrypt)
    rc = spec->encrypt (r_ciph, s_data, keyparms);
  else
    rc = GPG_ERR_NOT_IMPLEMENTED;

 leave:
  gcry_sexp_release (keyparms);
  return gcry_error (rc);
}