gen_card_key_with_backup (int algo, int keyno, int is_primary,
                          KBNODE pub_root, u32 timestamp,
                          u32 expireval, struct para_data_s *para)
{
#if ENABLE_CARD_SUPPORT && 0
  /* FIXME: Move this to gpg-agent.  */
  int rc;
  const char *s;
  PACKET *pkt;
  PKT_secret_key *sk, *sk_unprotected = NULL, *sk_protected = NULL;
  PKT_public_key *pk;
  size_t n;
  int i;
  unsigned int nbits;

  /* Get the size of the key directly from the card.  */
  {
    struct agent_card_info_s info;

    memset (&info, 0, sizeof info);
    if (!agent_scd_getattr ("KEY-ATTR", &info)
        && info.key_attr[1].algo)
      nbits = info.key_attr[1].nbits;
    else
      nbits = 1024; /* All pre-v2.0 cards.  */
    agent_release_card_info (&info);
  }

  /* Create a key of this size in memory.  */
  rc = generate_raw_key (algo, nbits, timestamp,
                         &sk_unprotected, &sk_protected);
  if (rc)
    return rc;

  /* Store the key to the card. */
  rc = save_unprotected_key_to_card (sk_unprotected, keyno);
  if (rc)
    {
      log_error (_("storing key onto card failed: %s\n"), gpg_strerror (rc));
      free_secret_key (sk_unprotected);
      free_secret_key (sk_protected);
      write_status_errcode ("save_key_to_card", rc);
      return rc;
    }

  /* Get rid of the secret key parameters and store the serial numer. */
  sk = sk_unprotected;
  n = pubkey_get_nskey (sk->pubkey_algo);
  for (i=pubkey_get_npkey (sk->pubkey_algo); i < n; i++)
    {
      gcry_mpi_release (sk->skey[i]);
      sk->skey[i] = NULL;
    }
  i = pubkey_get_npkey (sk->pubkey_algo);
  sk->skey[i] = gcry_mpi_set_opaque (NULL, xstrdup ("dummydata"), 10*8);
  sk->is_protected = 1;
  sk->protect.s2k.mode = 1002;
  s = get_parameter_value (para, pSERIALNO);
  assert (s);
  for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
       sk->protect.ivlen++, s += 2)
    sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s);

  /* Now write the *protected* secret key to the file.  */
  {
    char name_buffer[50];
    char *fname;
    IOBUF fp;
    mode_t oldmask;

    keyid_from_sk (sk, NULL);
    snprintf (name_buffer, sizeof name_buffer, "sk_%08lX%08lX.gpg",
              (ulong)sk->keyid[0], (ulong)sk->keyid[1]);

    fname = make_filename (backup_dir, name_buffer, NULL);
    /* Note that the umask call is not anymore needed because
       iobuf_create now takes care of it.  However, it does not harm
       and thus we keep it.  */
    oldmask = umask (077);
    if (is_secured_filename (fname))
      {
        fp = NULL;
        gpg_err_set_errno (EPERM);
      }
    else
      fp = iobuf_create (fname, 1);
    umask (oldmask);
    if (!fp)
      {
        rc = gpg_error_from_syserror ();
	log_error (_("can't create backup file '%s': %s\n"),
                   fname, strerror(errno) );
        xfree (fname);
        free_secret_key (sk_unprotected);
        free_secret_key (sk_protected);
        return rc;
      }

    pkt = xcalloc (1, sizeof *pkt);
    pkt->pkttype = PKT_SECRET_KEY;
    pkt->pkt.secret_key = sk_protected;
    sk_protected = NULL;

    rc = build_packet (fp, pkt);
    if (rc)
      {
        log_error("build packet failed: %s\n", gpg_strerror (rc));
        iobuf_cancel (fp);
      }
    else
      {
        unsigned char array[MAX_FINGERPRINT_LEN];
        char *fprbuf, *p;

        iobuf_close (fp);
        iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname);
        log_info (_("Note: backup of card key saved to '%s'\n"), fname);

        fingerprint_from_sk (sk, array, &n);
        p = fprbuf = xmalloc (MAX_FINGERPRINT_LEN*2 + 1 + 1);
        for (i=0; i < n ; i++, p += 2)
          sprintf (p, "%02X", array[i]);
        *p++ = ' ';
        *p = 0;

        write_status_text_and_buffer (STATUS_BACKUP_KEY_CREATED,
                                      fprbuf,
                                      fname, strlen (fname),
                                      0);
        xfree (fprbuf);
      }
    free_packet (pkt);
    xfree (pkt);
    xfree (fname);
    if (rc)
      {
        free_secret_key (sk_unprotected);
        return rc;
      }
  }

  /* Create the public key from the secret key. */
  pk = xcalloc (1, sizeof *pk );
  pk->timestamp = sk->timestamp;
  pk->version = sk->version;
  if (expireval)
      pk->expiredate = sk->expiredate = sk->timestamp + expireval;
  pk->pubkey_algo = sk->pubkey_algo;
  n = pubkey_get_npkey (sk->pubkey_algo);
  for (i=0; i < n; i++)
    pk->pkey[i] = mpi_copy (sk->skey[i]);

  /* Build packets and add them to the node lists.  */
  pkt = xcalloc (1,sizeof *pkt);
  pkt->pkttype = is_primary ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
  pkt->pkt.public_key = pk;
  add_kbnode(pub_root, new_kbnode( pkt ));

  pkt = xcalloc (1,sizeof *pkt);
  pkt->pkttype = is_primary ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY;
  pkt->pkt.secret_key = sk;
  add_kbnode(sec_root, new_kbnode( pkt ));

  return 0;
#else
# if __GCC__ && ENABLE_CARD_SUPPORT
#  warning Card support still missing
# endif
  (void)algo;
  (void)keyno;
  (void)is_primary;
  (void)pub_root;
  (void)timestamp;
  (void)expireval;
  (void)para;
  return gpg_error (GPG_ERR_NOT_SUPPORTED);
#endif /*!ENABLE_CARD_SUPPORT*/
}