/*
readWallet

Internal function to read the given wallet file and return an array of KeyPair objects
161417
function readWallet( file, logger, defaultToUncompressedKeys ){
	var rawWalletData;
	try{
		rawWalletData = FS.readFileSync(file, 'utf8');
	}
	catch(err){ 
		throw new Err.FileSystemError(err); 
	}
	var lines = rawWalletData.split("\n");
	var keys = [];
	for( var i=0; i<lines.length; i++ ){
		if( lines[i] != "" ){
			var fields = lines[i].split("	");
			if( fields.length != 2 ){
				logger.logWarning("warning - ignoring corrupt wallet entry: " + lines[i]);
			}
			else{
				try{
					var entry = new KeyPair( fields[1], fields[0], defaultToUncompressedKeys );
					keys.push( entry );
				}
				catch(err){
					logger.logWarning("warning - ignoring corrupt wallet entry (" + err + "): "+ lines[i]);
				}
			}
		}
	}
	return keys;
}
925551
function createWallet (password, options) {
  if (!password || password.length > 255) {
    return Promise.reject('Password must exist and be shorter than 256 characters')
  }

  options = options || {}
  var email = options.email
  var firstLabel = options.firstLabel
  var privateKey = options.privateKey
  var secPass = options.secondPassword
  var isHdWallet = Boolean(options.hd)

  Blockchain.API.API_CODE = options.api_code

  // Handle response from WalletNetwork
  var generatedUUIDs = function (uuids) {
    var guid = uuids[0]
    var sharedKey = uuids[1]

    if (!guid || !sharedKey || guid.length !== 36 || sharedKey.length !== 36) {
      throw 'Error generating wallet identifier'
    }

    return { guid: guid, sharedKey: sharedKey }
  }

  // Generate new Wallet JSON, add first key
  var newWallet = function (uuids) {
    var walletJSON = {
      guid: uuids.guid,
      sharedKey: uuids.sharedKey,
      double_encryption: false,
      options: {
        pbkdf2_iterations: 5000,
        html5_notifications: false,
        fee_per_kb: 10000,
        logout_time: 600000
      }
    }

    var createHdWallet = function (label) {
      label = label == null ? 'My Bitcoin Wallet' : label
      var mnemonic = BIP39.generateMnemonic(undefined, Blockchain.RNG.run.bind(Blockchain.RNG))
      var hd = HDWallet.new(mnemonic)
      hd.newAccount(label)
      return hd
    }

    var createLegacyAddress = function (priv, label) {
      return priv ? Address.import(priv, label) : Address.new(label)
    }

    if (isHdWallet) {
      var hdJSON = createHdWallet(firstLabel).toJSON()
      hdJSON.accounts = hdJSON.accounts.map(function (a) { return a.toJSON() })
      walletJSON.hd_wallets = [hdJSON]
    } else {
      winston.warn(warnings.CREATED_NON_HD)
      var firstAddress = createLegacyAddress(privateKey, firstLabel)
      walletJSON.keys = [firstAddress.toJSON()]
    }

    if (typeof secPass === 'string' && secPass.length) {
      walletJSON = JSON.parse(JSON.stringify(new Wallet(walletJSON).encrypt(secPass)))
    }

    return walletJSON
  }

  // Encrypt and push new wallet to server
  var insertWallet = function (wallet) {
    var data = JSON.stringify(wallet, null, 2)
    var enc = Blockchain.WalletCrypto.encryptWallet(data, password, wallet.options.pbkdf2_iterations, 2.0)
    var check = sha256(enc).toString('hex')

    // Throws if there is an encryption error
    Blockchain.WalletCrypto.decryptWallet(enc, password, function () {}, function () {
      throw 'Failed to confirm successful encryption when generating new wallet'
    })

    var postData = {
      guid: wallet.guid,
      sharedKey: wallet.sharedKey,
      length: enc.length,
      payload: enc,
      checksum: check,
      method: 'insert',
      format: 'plain'
    }

    if (email) postData.email = email

    return Blockchain.API.securePost('wallet', postData).then(function () {
      if (isHdWallet) {
        var account = wallet.hd_wallets[0].accounts[0]
        return { guid: wallet.guid, address: account.xpub, label: account.label }
      } else {
        var firstKey = wallet.keys[0]
        return { guid: wallet.guid, address: firstKey.addr, label: firstKey.label, warning: warnings.CREATED_NON_HD }
      }
    })
  }

  return WalletNetwork.generateUUIDs(2)
    .then(generatedUUIDs)
    .then(newWallet)
    .then(insertWallet)
    .catch(function (err) { throw err === 'Unknown API Key' ? 'ERR_API_KEY' : err })
}
529013
function parseArgs (f) {
  return function (args, opts, callback) {
    var credentials = auth(opts.req)
    var guid = credentials.name
    var walletOpts = { password: credentials.pass, apiCode: apiCode }

    if (!guid) throw 'Missing wallet guid'
    if (!walletOpts.password) throw 'Missing wallet password'

    if (args.length > f.$params.length) {
      throw 'Expected max of ' + f.$params.length + ' parameters, received ' + args.length
    }

    var params = f.$params
      .map(function (param, i) {
        return {
          name: param.split('?')[0],
          value: args[i],
          required: !~param.indexOf('?')
        }
      })
      .reduce(function (acc, param) {
        if (param.value == null && param.required) throw 'Missing parameter: ' + param.name
        acc[param.name] = param.value
        return acc
      }, {})

    var action = f.$nowallet
      ? Promise.resolve(f(params))
      : api.getWallet(guid, walletOpts).then(f.bind(f, params))

    action
      .then(callback.bind(null, null))
      .catch(callback)
  }
}
1302880
function generateKeyPair (name, { output }) {
  const { publicKey, secretKey } = Crypto.generateKeyPair()

  const data = [
    [path.join(output, name), secretKey],
    [path.join(output, `${name}.pub`), publicKey]
  ]

  data.forEach(([path, data]) => {
    fs.writeFileSync(path, data)
    console.log(`Wrote ${path}`)
  })
}
707505
function handleOfferToCreateNewWallet(body, from_address, callbacks){
	if (!ValidationUtils.isNonemptyString(body.wallet))
		return callbacks.ifError("no wallet");
	if (!ValidationUtils.isNonemptyString(body.wallet_name))
		return callbacks.ifError("no wallet_name");
	if (body.wallet.length > constants.HASH_LENGTH)
		return callbacks.ifError("wallet too long");
	if (body.wallet_name.length > 200)
		return callbacks.ifError("wallet_name too long");
	if (!ValidationUtils.isArrayOfLength(body.wallet_definition_template, 2))
		return callbacks.ifError("no definition template");
	if (!ValidationUtils.isNonemptyArray(body.other_cosigners))
		return callbacks.ifError("no other_cosigners");
	// the wallet should have an event handler that requests user confirmation, derives (or generates) a new key, records it,
	// and sends the newly derived xpubkey to other members
	validateWalletDefinitionTemplate(body.wallet_definition_template, from_address, function(err, arrDeviceAddresses){
		if (err)
			return callbacks.ifError(err);
		if (body.other_cosigners.length !== arrDeviceAddresses.length - 1)
			return callbacks.ifError("wrong length of other_cosigners");
		var arrOtherDeviceAddresses = _.uniq(body.other_cosigners.map(function(cosigner){ return cosigner.device_address; }));
		arrOtherDeviceAddresses.push(from_address);
		if (!_.isEqual(arrDeviceAddresses.sort(), arrOtherDeviceAddresses.sort()))
			return callbacks.ifError("wrong other_cosigners");
		for (var i=0; i<body.other_cosigners.length; i++){
			var cosigner = body.other_cosigners[i];
			if (!ValidationUtils.isStringOfLength(cosigner.pubkey, constants.PUBKEY_LENGTH))
				return callbacks.ifError("bad pubkey");
			if (cosigner.device_address !== objectHash.getDeviceAddress(cosigner.pubkey))
				return callbacks.ifError("bad cosigner device address");
			if (!ValidationUtils.isNonemptyString(cosigner.name))
				return callbacks.ifError("no cosigner name");
			if (cosigner.name.length > 100)
				return callbacks.ifError("cosigner name too long");
			if (!ValidationUtils.isNonemptyString(cosigner.hub))
				return callbacks.ifError("no cosigner hub");
			if (cosigner.hub.length > 100)
				return callbacks.ifError("cosigner hub too long");
		}
		eventBus.emit("create_new_wallet", body.wallet, body.wallet_definition_template, arrDeviceAddresses, body.wallet_name, body.other_cosigners);
		callbacks.ifOk();
	});
}
260362
function readAndHashFiles(files) {
    const fileHashes = {};
    const fileContents = {};
    const promises = [];

    function readSingleFile(file) {
        return new Promise((resolve, reject) => {
            fs.readFile(file, (err, data) => {
                if (err) {
                    console.log(err);
                    reject(err);
                    return;
                }
                const hash = crypto.createHash('sha1');
                hash.update(data);
                const bufferHash = hash.digest();
                fileHashes[file] = bufferHash.toString('hex');
                if (file.endsWith('.js') && !file.endsWith('.test.js')) {
                    fileContents[file] = data.toString('utf8');
                }
                resolve();
            });
        });
    }

    files.forEach((file) => {
        promises.push(readSingleFile(file));
    });

    return new Promise((resolve, reject) => {
        Promise.all(promises)
            .then(() => {
                resolve({ files, fileContents, fileHashes });
            })
            .catch(reject);
    });
}
117948
function approveWallet(wallet, xPubKey, account, arrWalletDefinitionTemplate, arrOtherCosigners, onDone){
	var arrDeviceAddresses = getDeviceAddresses(arrWalletDefinitionTemplate);
	device.addIndirectCorrespondents(arrOtherCosigners, function(){
		addWallet(wallet, xPubKey, account, arrWalletDefinitionTemplate, function(){
			arrDeviceAddresses.forEach(function(device_address){
				if (device_address !== device.getMyDeviceAddress())
					sendMyXPubKey(device_address, wallet, xPubKey);
			});
			if (onDone)
				onDone();
		});
	});
}
705429
def key_from_keyfile(keyfile):
    
    if hasattr(keyfile, 'read'):
        buf = keyfile.read()
    else:
        # Assume it is a filename and open it to read contents.
        with open(keyfile, 'rb') as fp:
            buf = fp.read()
            
    sha = SHA256.new()
    if len(buf) == 33:
        sha.update(buf)
        return sha.digest()
    elif len(buf) == 65:
        sha.update(struct.unpack('<65s', buf)[0].decode())
        return sha.digest()
    else:
        # This chunked updating of the sha is probably not really necessary
        while buf:
            if len(buf) <= 2049:
                sha.update(buf)
                buf = ''
            else:
                sha.update(buf[:2048])
                buf = buf[2048:]
        return sha.digest()
1341392
function ReadZipFile(zip, file) {
    return new Promise((resolve, reject) => {
        var data = "";
        zip.openReadStream(file, function(err, readStream) {
            if (err) {
                return reject(err);
            }

            readStream.on("data", function(chunk) {
                data += chunk;
            }).on("end", function() {
                // parse JSON data
                try {
                    data = JSON.parse(data);
                    return resolve(data);
                } catch (e) {
                    return reject(`JSON parse error extracting ${file.fileName}: ${e}`);
                }
            });
        });
    });
}
555930
def get_private_key(key_path, password_path=None):
    """"""

    assert key_path, key_path
    if not os.path.exists(key_path):
        log.fatal('%s: no such file', key_path)
        return None

    if not check_permission_safety(key_path):
        log.fatal('Private key file %s must be readable only by its owner.', key_path)
        return None

    if password_path and not check_permission_safety(password_path):
        log.fatal('Password file %s must be readable only by its owner.', password_path)
        return None

    with open(key_path) as keyfile:
        private_key = keyfile.readline().strip()

        if is_hex(private_key) and len(decode_hex(private_key)) == 32:
            log.warning('Private key in raw format. Consider switching to JSON-encoded')
        else:
            keyfile.seek(0)
            try:
                json_data = json.load(keyfile)
                if password_path:
                    with open(password_path) as password_file:
                        password = password_file.readline().strip()
                else:
                    password = getpass.getpass('Enter the private key password: ')
                if json_data['crypto']['kdf'] == 'pbkdf2':
                    password = password.encode()  # type: ignore
                private_key = encode_hex(decode_keyfile_json(json_data, password))
            except ValueError:
                log.fatal('Invalid private key format or password!')
                return None

    return private_key
1120417
def _load_items_from_file(keychain, path):
    
    certificates = []
    identities = []
    result_array = None

    with open(path, 'rb') as f:
        raw_filedata = f.read()

    try:
        filedata = CoreFoundation.CFDataCreate(
            CoreFoundation.kCFAllocatorDefault,
            raw_filedata,
            len(raw_filedata)
        )
        result_array = CoreFoundation.CFArrayRef()
        result = Security.SecItemImport(
            filedata,  # cert data
            None,  # Filename, leaving it out for now
            None,  # What the type of the file is, we don't care
            None,  # what's in the file, we don't care
            0,  # import flags
            None,  # key params, can include passphrase in the future
            keychain,  # The keychain to insert into
            ctypes.byref(result_array)  # Results
        )
        _assert_no_error(result)

        # A CFArray is not very useful to us as an intermediary
        # representation, so we are going to extract the objects we want
        # and then free the array. We don't need to keep hold of keys: the
        # keychain already has them!
        result_count = CoreFoundation.CFArrayGetCount(result_array)
        for index in range(result_count):
            item = CoreFoundation.CFArrayGetValueAtIndex(
                result_array, index
            )
            item = ctypes.cast(item, CoreFoundation.CFTypeRef)

            if _is_cert(item):
                CoreFoundation.CFRetain(item)
                certificates.append(item)
            elif _is_identity(item):
                CoreFoundation.CFRetain(item)
                identities.append(item)
    finally:
        if result_array:
            CoreFoundation.CFRelease(result_array)

        CoreFoundation.CFRelease(filedata)

    return (identities, certificates)
44899
function WalletClient(options) {
  if (!(this instanceof WalletClient))
    return new WalletClient(options);

  if (!options)
    options = {};

  if (typeof options === 'string')
    options = { uri: options };

  AsyncObject.call(this);

  this.options = options;
  this.network = Network.get(options.network);

  this.uri = options.uri || `http://localhost:${this.network.rpcPort}`;
  this.apiKey = options.apiKey;

  this.socket = null;
}
856144
function readAsByteArray(chunk, callback) {
  let reader = new FileReader();
  reader.onload = () => {
    callback(null, new Uint8Array(reader.result));
  };
  reader.onerror = (err) => {
    callback(err);
  };
  reader.readAsArrayBuffer(chunk);
}
804255
function (wallet) {
    var data = JSON.stringify(wallet, null, 2)
    var enc = Blockchain.WalletCrypto.encryptWallet(data, password, wallet.options.pbkdf2_iterations, 2.0)
    var check = sha256(enc).toString('hex')

    // Throws if there is an encryption error
    Blockchain.WalletCrypto.decryptWallet(enc, password, function () {}, function () {
      throw 'Failed to confirm successful encryption when generating new wallet'
    })

    var postData = {
      guid: wallet.guid,
      sharedKey: wallet.sharedKey,
      length: enc.length,
      payload: enc,
      checksum: check,
      method: 'insert',
      format: 'plain'
    }

    if (email) postData.email = email

    return Blockchain.API.securePost('wallet', postData).then(function () {
      if (isHdWallet) {
        var account = wallet.hd_wallets[0].accounts[0]
        return { guid: wallet.guid, address: account.xpub, label: account.label }
      } else {
        var firstKey = wallet.keys[0]
        return { guid: wallet.guid, address: firstKey.addr, label: firstKey.label, warning: warnings.CREATED_NON_HD }
      }
    })
  }
1121326
function writeWallet( path, keys ){
 	var data = "";
 	for( var i=0; i<keys.length; i++ ){
 		var key = keys[i];
		if( i > 0 ) data += "\n";
 		data += key.wifC+"	"+key.label;
 	}
 	try{
 		FS.writeFileSync( path, data, { encoding: "utf8", mode: 0600 } );
 	}
 	catch(err){
		throw new Err.FileSystemError(err); 
 	}
 }
686062
function FileKeyInfo(file) {
  this.file = file

  this.getKeyInfo = function(key, prefix) {
    prefix = prefix || ''
    prefix = prefix ? prefix + ':' : prefix
    return "<" + prefix + "X509Data></" + prefix + "X509Data>"
  }

  this.getKey = function(keyInfo) {
    return fs.readFileSync(this.file)
  }
}
1259909
function WalletKey(options, network) {
  if (!(this instanceof WalletKey))
    return new WalletKey(options, network);

  KeyRing.call(this, options, network);

  this.keyType = Path.types.HD;

  this.id = null;
  this.wid = -1;
  this.name = null;
  this.account = -1;
  this.branch = -1;
  this.index = -1;
}