Exemple #1
0
static char *
wallet_encrypt_string(struct wallet    *wallet,
                      const char       *plaintext,
                      struct crypt_key *ckey)
{
   struct secure_area *sec;
   char cipherStr[1024];
   uint8 *cipher;
   char *hmac;
   char *res;
   size_t clen;
   size_t len;
   bool s;

   ASSERT(plaintext);

   len = strlen(plaintext) + 1;
   sec = secure_alloc(len);
   memcpy(sec->buf, plaintext, len);

   s = crypt_encrypt(ckey, sec, &cipher, &clen);
   ASSERT(s);

   str_snprintf_bytes(cipherStr, sizeof cipherStr, NULL, cipher, clen);
   hmac = wallet_hmac_string(cipher, clen, wallet->pass);
   res = safe_asprintf("%s-%s", cipherStr, hmac);
   free(hmac);

   free(cipher);
   secure_free(sec);

   return res;
}
Exemple #2
0
static int
wallet_save_keys(struct wallet *wallet)
{
   struct config *cfg;
   int res;
   int n;

   n = hashtable_getnumentries(wallet->hash_keys);

   Log(LGPFX" saving %u key%s in %sencrypted wallet %s.\n",
       n, n > 1 ? "s" : "",
       wallet->pass ? "encrypted" : "NON-",
       wallet->filename);

   cfg = config_create();
   config_setint64(cfg, n, "numKeys");

   if (wallet->pass) {
      char saltStr[80];
      int64 count = 0;
      bool s;

      res = RAND_bytes(wallet->ckey->salt, sizeof wallet->ckey->salt);
      if (res != 1) {
         res = ERR_get_error();
         Log(LGPFX" RAND_bytes failed: %d\n", res);
         goto exit;
      }
      str_snprintf_bytes(saltStr, sizeof saltStr, NULL,
                         wallet->ckey->salt, sizeof wallet->ckey->salt);
      config_setstring(cfg, saltStr, "encryption.salt");
      s = crypt_set_key_from_passphrase(wallet->pass, wallet->ckey, &count);
      ASSERT(s);
      ASSERT(count >= CRYPT_NUM_ITERATIONS_OLD);
      config_setint64(cfg, count, "encryption.numIterations");
   }

   hashtable_for_each(wallet->hash_keys, wallet_save_key_cb, cfg);

   file_rotate(wallet->filename, 1);
   res = file_create(wallet->filename);
   if (res) {
      Log(LGPFX" failed to create file '%s': %s\n",
          wallet->filename, strerror(res));
      goto exit;
   }
   res = file_chmod(wallet->filename, 0600);
   if (res) {
      Log(LGPFX" failed to chmod 0600 wallet.dat: %s\n",
          strerror(res));
      goto exit;
   }
   res = config_write(cfg, wallet->filename);

exit:
   config_free(cfg);

   return res;
}
Exemple #3
0
void
Log_Bytes(const char *pfx,
          const void *data,
          size_t len)
{
   char str[16384];

   str_snprintf_bytes(str, sizeof str, pfx, data, len);

   Log("%s\n", str);
}
Exemple #4
0
static char *
wallet_hmac_string(const uint8 *privkey,
                   size_t       privlen,
                   const struct secure_area *passphrase)
{
   char result[128];
   uint256 hmac;

   ASSERT(privkey);

   crypt_hmac_sha256(privkey, privlen, passphrase->buf, passphrase->len, &hmac);
   str_snprintf_bytes(result, sizeof result, NULL, hmac.data, sizeof hmac);

   return safe_strdup(result);
}
Exemple #5
0
static void
wallet_save_key_cb(const void *key,
                   size_t klen,
                   void *clientData,
                   void *keyData)
{
   struct wallet_key *wkey = (struct wallet_key *)keyData;
   struct config *wcfg = (struct config *)clientData;
   uint8 *privkey;
   uint8 *pubkey;
   size_t privlen;
   size_t publen;
   char *privStr;
   char pubStr[256];

   key_get_privkey(wkey->key, &privkey, &privlen);
   key_get_pubkey(wkey->key,  &pubkey,  &publen);

   privStr = b58_bytes_to_privkey(privkey, privlen);
   str_snprintf_bytes(pubStr, sizeof pubStr, NULL, pubkey, publen);

   config_setint64(wcfg, wkey->birth,    "key%u.birth",  wkey->cfg_idx);
   config_setstring(wcfg, wkey->desc,    "key%u.desc",   wkey->cfg_idx);
   config_setstring(wcfg, pubStr,        "key%u.pubkey", wkey->cfg_idx);
   config_setbool(wcfg, wkey->spendable, "key%u.spendable", wkey->cfg_idx);

   if (btc->wallet->pass) {
      char *enc = wallet_encrypt_string(btc->wallet, privStr, btc->wallet->ckey);
      free(privStr);
      privStr = enc;
   }
   config_setstring(wcfg, privStr, "key%u.privkey", wkey->cfg_idx);

   free(pubkey);
   free(privkey);
   free(privStr);
}