prepare_unprotect (int pubkey_algo, gcry_mpi_t *skey, size_t skeysize,
                   int s2k_mode,
                   unsigned int *r_npkey, unsigned int *r_nskey,
                   unsigned int *r_skeylen)
{
  size_t npkey, nskey, skeylen;
  int i;

  /* Count the actual number of MPIs is in the array and set the
     remainder to NULL for easier processing later on.  */
  for (skeylen = 0; skey[skeylen]; skeylen++)
    ;
  for (i=skeylen; i < skeysize; i++)
    skey[i] = NULL;

  /* Check some args.  */
  if (s2k_mode == 1001)
    {
      /* Stub key.  */
      log_info (_("secret key parts are not available\n"));
      return gpg_error (GPG_ERR_UNUSABLE_SECKEY);
    }

  if (gcry_pk_test_algo (pubkey_algo))
    {
      log_info (_("public key algorithm %d (%s) is not supported\n"),
                pubkey_algo, gcry_pk_algo_name (pubkey_algo));
      return gpg_error (GPG_ERR_PUBKEY_ALGO);
    }

  /* Get properties of the public key algorithm and do some
     consistency checks.  Note that we need at least NPKEY+1 elements
     in the SKEY array. */
  get_npkey_nskey (pubkey_algo, &npkey, &nskey);
  if (!npkey || !nskey || npkey >= nskey)
    return gpg_error (GPG_ERR_INTERNAL);
  if (skeylen <= npkey)
    return gpg_error (GPG_ERR_MISSING_VALUE);
  if (nskey+1 >= skeysize)
    return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);

  /* Check that the public key parameters are all available and not
     encrypted.  */
  for (i=0; i < npkey; i++)
    {
      if (!skey[i] || gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_USER1))
        return gpg_error (GPG_ERR_BAD_SECKEY);
    }

  if (r_npkey)
    *r_npkey = npkey;
  if (r_nskey)
    *r_nskey = nskey;
  if (r_skeylen)
    *r_skeylen = skeylen;
  return 0;
}
prepare_unprotect (int pubkey_algo, gcry_mpi_t *skey, size_t skeysize,
                   int s2k_mode,
                   unsigned int *r_npkey, unsigned int *r_nskey,
                   unsigned int *r_skeylen)
{
  size_t npkey, nskey, skeylen;
  int i;

   
  for (skeylen = 0; skey[skeylen]; skeylen++)
    ;
  for (i=skeylen; i < skeysize; i++)
    skey[i] = NULL;

   
  if (s2k_mode == 1001)
    {
       
      log_info (_("secret key parts are not available\n"));
      return gpg_error (GPG_ERR_UNUSABLE_SECKEY);
    }

  if (gcry_pk_test_algo (pubkey_algo))
    {
      log_info (_("public key algorithm %d (%s) is not supported\n"),
                pubkey_algo, gcry_pk_algo_name (pubkey_algo));
      return gpg_error (GPG_ERR_PUBKEY_ALGO);
    }

   
  get_npkey_nskey (pubkey_algo, &npkey, &nskey);
  if (!npkey || !nskey || npkey >= nskey)
    return gpg_error (GPG_ERR_INTERNAL);
  if (skeylen <= npkey)
    return gpg_error (GPG_ERR_MISSING_VALUE);
  if (nskey+1 >= skeysize)
    return gpg_error (GPG_ERR_BUFFER_TOO_SHORT);

   
  for (i=0; i < npkey; i++)
    {
      if (!skey[i] || gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_USER1))
        return gpg_error (GPG_ERR_BAD_SECKEY);
    }

  if (r_npkey)
    *r_npkey = npkey;
  if (r_nskey)
    *r_nskey = nskey;
  if (r_skeylen)
    *r_skeylen = skeylen;
  return 0;
}