def create_wallet_file(pwd, seed):
    password_key = btc.bin_dbl_sha256(pwd)
    encrypted_seed = encryptData(password_key, seed.decode('hex'))
    timestamp = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
    return json.dumps({'creator': 'joinmarket project',
                             'creation_time': timestamp,
                             'encrypted_seed': encrypted_seed.encode('hex'),
                             'network': get_network()})
Exemple #2
0
    def read_wallet_file_data(self, filename, pwd=None, wallet_dir=None):
        self.path = None
        wallet_dir = wallet_dir if wallet_dir else 'wallets'
        self.index_cache = [[0, 0]] * self.max_mix_depth
        path = os.path.join(wallet_dir, filename)
        if not os.path.isfile(path):
            if get_network() == 'testnet':
                log.debug('filename interpreted as seed, only available in '
                          'testnet because this probably has lower entropy')
                return "FAKESEED" + filename
            else:
                raise IOError('wallet file not found')
        if not pwd:
            log.info("Password required for non-testnet seed wallet")
            return None
        self.path = path
        fd = open(path, 'r')
        walletfile = fd.read()
        fd.close()
        walletdata = json.loads(walletfile)
        if walletdata['network'] != get_network():
            raise ValueError('wallet network(%s) does not match '
                             'joinmarket configured network(%s)' %
                             (walletdata['network'], get_network()))
        if 'index_cache' in walletdata:
            self.index_cache = walletdata['index_cache']
            if self.max_mix_depth > len(self.index_cache):
                #This can happen e.g. in tumbler when we need more mixdepths
                #than currently exist. Since we have no info for those extra
                #depths, we must default to (0,0) (but sync should find used
                #adddresses).
                self.index_cache += [[0, 0]] * (self.max_mix_depth -
                                                len(self.index_cache))
        password_key = btc.bin_dbl_sha256(pwd)
        if 'encrypted_seed' in walletdata:  #accept old field name
            encrypted_entropy = walletdata['encrypted_seed']
        elif 'encrypted_entropy' in walletdata:
            encrypted_entropy = walletdata['encrypted_entropy']
        try:
            decrypted_entropy = decryptData(
                password_key, encrypted_entropy.decode('hex')).encode('hex')
            # there is a small probability of getting a valid PKCS7
            # padding by chance from a wrong password; sanity check the
            # seed length
            if len(decrypted_entropy) != 32:
                raise ValueError
        except ValueError:
            log.info('Incorrect password')
            return None

        if 'encrypted_mnemonic_extension' in walletdata:
            try:
                cleartext = decryptData(
                    password_key,
                    walletdata['encrypted_mnemonic_extension'].decode('hex'))
                #theres a small chance of not getting a ValueError from the wrong
                # password so also check the sum
                if cleartext[-9] != '\xff':
                    raise ValueError
                chunks = cleartext.split('\xff')
                if len(chunks) < 3 or cleartext[-8:] != btc.dbl_sha256(
                        chunks[1])[:8]:
                    raise ValueError
                mnemonic_extension = chunks[1]
            except ValueError:
                log.info('incorrect password')
                return None
        else:
            mnemonic_extension = None

        if self.storepassword:
            self.password_key = password_key
            self.walletdata = walletdata
        if 'imported_keys' in walletdata:
            for epk_m in walletdata['imported_keys']:
                privkey = decryptData(
                    password_key,
                    epk_m['encrypted_privkey'].decode('hex')).encode('hex')
                #Imported keys are stored as 32 byte strings only, so the
                #second version below is sufficient, really.
                if len(privkey) != 64:
                    raise Exception(
                        "Unexpected privkey format; already compressed?:" +
                        privkey)
                privkey += "01"
                if epk_m['mixdepth'] not in self.imported_privkeys:
                    self.imported_privkeys[epk_m['mixdepth']] = []
                self.addr_cache[btc.privtoaddr(
                    privkey, magicbyte=get_p2pk_vbyte())] = (
                        epk_m['mixdepth'], -1,
                        len(self.imported_privkeys[epk_m['mixdepth']]))
                self.imported_privkeys[epk_m['mixdepth']].append(privkey)

        if mnemonic_extension:
            return (decrypted_entropy, mnemonic_extension)
        else:
            return decrypted_entropy
Exemple #3
0
 def read_wallet_file_data(self, filename):
     self.path = None
     self.index_cache = [[0, 0]] * self.max_mix_depth
     path = os.path.join('wallets', filename)
     if not os.path.isfile(path):
         if get_network() == 'testnet':
             log.debug('filename interpreted as seed, only available in '
                       'testnet because this probably has lower entropy')
             return filename
         else:
             raise IOError('wallet file not found')
     self.path = path
     fd = open(path, 'r')
     walletfile = fd.read()
     fd.close()
     walletdata = json.loads(walletfile)
     if walletdata['network'] != get_network():
         print ('wallet network(%s) does not match '
                'joinmarket configured network(%s)' % (
             walletdata['network'], get_network()))
         sys.exit(0)
     if 'index_cache' in walletdata:
         self.index_cache = walletdata['index_cache']
     decrypted = False
     while not decrypted:
         password = getpass('Enter wallet decryption passphrase: ')
         password_key = btc.bin_dbl_sha256(password)
         encrypted_seed = walletdata['encrypted_seed']
         try:
             decrypted_seed = decryptData(
                     password_key,
                     encrypted_seed.decode('hex')).encode('hex')
             # there is a small probability of getting a valid PKCS7
             # padding by chance from a wrong password; sanity check the
             # seed length
             if len(decrypted_seed) == 32:
                 decrypted = True
             else:
                 raise ValueError
         except ValueError:
             print('Incorrect password')
             decrypted = False
     if self.storepassword:
         self.password_key = password_key
         self.walletdata = walletdata
     if 'imported_keys' in walletdata:
         for epk_m in walletdata['imported_keys']:
             privkey = decryptData(
                     password_key,
                     epk_m['encrypted_privkey'].decode( 'hex')).encode('hex')
             #Imported keys are stored as 32 byte strings only, so the
             #second version below is sufficient, really.
             if not btc.secp_present:
                 privkey = btc.encode_privkey(privkey, 'hex_compressed')
             else:
                 if len(privkey) != 64:
                     raise Exception(
                     "Unexpected privkey format; already compressed?:" + privkey)
                 privkey += "01"
             if epk_m['mixdepth'] not in self.imported_privkeys:
                 self.imported_privkeys[epk_m['mixdepth']] = []
             self.addr_cache[btc.privtoaddr(
                     privkey, magicbyte=get_p2pk_vbyte())] = (epk_m['mixdepth'], -1,
                 len(self.imported_privkeys[epk_m['mixdepth']]))
             self.imported_privkeys[epk_m['mixdepth']].append(privkey)
     return decrypted_seed
Exemple #4
0
 def read_wallet_file_data(self, filename):
     self.path = None
     self.index_cache = [[0, 0]] * self.max_mix_depth
     path = os.path.join('wallets', filename)
     if not os.path.isfile(path):
         if get_network() == 'testnet':
             log.debug('filename interpreted as seed, only available in '
                       'testnet because this probably has lower entropy')
             return filename
         else:
             raise IOError('wallet file not found')
     self.path = path
     fd = open(path, 'r')
     walletfile = fd.read()
     fd.close()
     walletdata = json.loads(walletfile)
     if walletdata['network'] != get_network():
         print('wallet network(%s) does not match '
               'joinmarket configured network(%s)' %
               (walletdata['network'], get_network()))
         sys.exit(0)
     if 'index_cache' in walletdata:
         self.index_cache = walletdata['index_cache']
     decrypted = False
     while not decrypted:
         password = getpass('Enter wallet decryption passphrase: ')
         password_key = btc.bin_dbl_sha256(password)
         encrypted_seed = walletdata['encrypted_seed']
         try:
             decrypted_seed = decryptData(
                 password_key, encrypted_seed.decode('hex')).encode('hex')
             # there is a small probability of getting a valid PKCS7
             # padding by chance from a wrong password; sanity check the
             # seed length
             if len(decrypted_seed) == 32:
                 decrypted = True
             else:
                 raise ValueError
         except ValueError:
             print('Incorrect password')
             decrypted = False
     if self.storepassword:
         self.password_key = password_key
         self.walletdata = walletdata
     if 'imported_keys' in walletdata:
         for epk_m in walletdata['imported_keys']:
             privkey = decryptData(
                 password_key,
                 epk_m['encrypted_privkey'].decode('hex')).encode('hex')
             #Imported keys are stored as 32 byte strings only, so the
             #second version below is sufficient, really.
             if not btc.secp_present:
                 privkey = btc.encode_privkey(privkey, 'hex_compressed')
             else:
                 if len(privkey) != 64:
                     raise Exception(
                         "Unexpected privkey format; already compressed?:" +
                         privkey)
                 privkey += "01"
             if epk_m['mixdepth'] not in self.imported_privkeys:
                 self.imported_privkeys[epk_m['mixdepth']] = []
             self.addr_cache[btc.privtoaddr(
                 privkey, magicbyte=get_p2pk_vbyte())] = (
                     epk_m['mixdepth'], -1,
                     len(self.imported_privkeys[epk_m['mixdepth']]))
             self.imported_privkeys[epk_m['mixdepth']].append(privkey)
     return decrypted_seed