Skip to content
This repository has been archived by the owner on Nov 21, 2019. It is now read-only.

BitBox #2172

Merged
merged 2 commits into from
Dec 5, 2018
Merged

BitBox #2172

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Check gh-pages files against live website at https://www.myetherwallet.com
| File Name| Status|
|---|---|
| index.html |![embedded.html](https://filechecker.myetherwallet.com/check?localFile=https://raw.githubusercontent.com/kvhnuke/etherwallet/gh-pages/index.html&remoteFile=https://www.myetherwallet.com/index.html)|
| embedded.html |![embedded.html](https://filechecker.myetherwallet.com/check?localFile=https://raw.githubusercontent.com/kvhnuke/etherwallet/gh-pages/embedded.html&remoteFile=https://www.myetherwallet.com/embedded.html)|
| embedded.html |![embedded.html](https://filechecker.myetherwallet.com/check?localFile=https://raw.githubusercontent.com/kvhnuke/etherwallet/gh-pages/embedded.html&remoteFile=https://www.myetherwallet.com/embedded.html)|
| helpers.html |![embedded.html](https://filechecker.myetherwallet.com/check?localFile=https://raw.githubusercontent.com/kvhnuke/etherwallet/gh-pages/helpers.html&remoteFile=https://www.myetherwallet.com/helpers.html)|
| signmsg.html |![signmsg.html](https://filechecker.myetherwallet.com/check?localFile=https://raw.githubusercontent.com/kvhnuke/etherwallet/gh-pages/signmsg.html&remoteFile=https://www.myetherwallet.com/signmsg.html)|
| bin/startMEW.js |![startMEW.js](https://filechecker.myetherwallet.com/check?localFile=https://raw.githubusercontent.com/kvhnuke/etherwallet/gh-pages/bin/startMEW.js&remoteFile=https://www.myetherwallet.com/bin/startMEW.js)|
Expand Down Expand Up @@ -64,10 +64,10 @@ Check gh-pages files against live website at https://www.myetherwallet.com
#### Features

- Create new wallets completely client side.
- Access your wallet via unencrypted private key, encrypted private key, keystore files, mnemonics, or Digital Bitbox, Ledger Nano S or TREZOR hardware wallet.
- Access your wallet via unencrypted private key, encrypted private key, keystore files, mnemonics, or BitBox, Ledger Nano S or TREZOR hardware wallet.
- Easily send ETH and *any* ERC-20 Standard Token. [Many tokens included as default.](https://myetherwallet.groovehq.com/knowledge_base/topics/can-i-send-my-steem-slash-btc-slash-ltc-slash-nem-slash-to-myetherwallet)
- Generate, sign & send transactions offline, ensuring your private keys never touch an internet-connected device.
- Securely access your ETH & Tokens on your [Digital Bitbox, Ledger or TREZOR Hardware Wallet](https://myetherwallet.groovehq.com/knowledge_base/topics/hardware-wallet-recommends) via the MyEtherWallet interface (Chrome & Opera natively, Firefox w/ [add-on](https://addons.mozilla.org/en-US/firefox/addon/u2f-support-add-on/))
- Securely access your ETH & Tokens on your [BitBox, Ledger or TREZOR Hardware Wallet](https://myetherwallet.groovehq.com/knowledge_base/topics/hardware-wallet-recommends) via the MyEtherWallet interface (Chrome & Opera natively, Firefox w/ [add-on](https://addons.mozilla.org/en-US/firefox/addon/u2f-support-add-on/))
- Now in 18 languages thanks 100% to the amazing Ethereum community.
- Supports URI Strings on Send Transaction Page.
- to=[address]
Expand Down
2 changes: 1 addition & 1 deletion app/includes/footer.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
<div class="footer__pill-wrap footer__pill-custom-wrap">
<a class="footer__pill" href="https://www.ledger.com/products/ledger-nano-s?r=fa4b" target="_blank" rel="noopener">Ledger Wallet</a>
<a class="footer__pill" href="https://trezor.io/?a=myetherwallet.com" target="_blank" rel="noopener">TREZOR</a>
<a class="footer__pill" href="http://shiftcrypto.ositracker.com/91316/7114" target="_blank" rel="noopener">Digital Bitbox</a>
<a class="footer__pill" href="http://shiftcrypto.ositracker.com/91316/7114" target="_blank" rel="noopener">BitBox</a>
<a class="footer__pill" href="https://ether.cards/?utm_source=mew&utm_medium=cpm&utm_campaign=site" target="_blank" rel="noopener">ether.card</a>
<a class="footer__pill" href="https://thehodlwallet.com?aff=15" target="_blank" rel="noopener">HODL Wallet</a>
<a class="footer__pill" href="http://billfodl.com?afmc=2j&utm_campaign=2j&utm_source=leaddyno&utm_medium=affiliate" target="_blank" rel="noopener">Billfodl</a>
Expand Down
2 changes: 1 addition & 1 deletion app/includes/generateWallet.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
<li>
<p>
<strong>
Ledger / TREZOR / Digital Bitbox / Secalot
Ledger / TREZOR / BitBox / Secalot
</strong>:
<span translate="GEN_Help_1">
Use your
Expand Down
2 changes: 1 addition & 1 deletion app/scripts/controllers/signMsgCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ var signMsgCtrl = function($scope, $sce, walletService) {
localCallback
);

// Sign via Digital Bitbox
// Sign via BitBox
} else if (typeof hwType != "undefined" && hwType == "digitalBitbox") {
var msg = ethUtil.hashPersonalMessage(ethUtil.toBuffer(thisMessage));
var localCallback = function(signed, error) {
Expand Down
22 changes: 11 additions & 11 deletions app/scripts/directives/walletDecryptDrtv.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ <h4 translate="decrypt_Access">
ng-show="ajaxReq.type=='ETH'||ajaxReq.type=='ETC'||ajaxReq.type=='ROPSTEN ETH'||ajaxReq.type=='RINKEBY ETH'||ajaxReq.type=='KOVAN ETH'||ajaxReq.type=='EXP'">
<input aria-flowto="aria5"
type="radio"
aria-label="Digital Bitbox hardware wallet"
aria-label="BitBox hardware wallet"
ng-model="walletType"
value="digitalBitbox"/>
Digital Bitbox
BitBox
</label>

<!-- Secalot -->
Expand Down Expand Up @@ -413,7 +413,7 @@ <h5>
<!-- Digital Bitbox-->
<div id="selectedTypeDigitalBitbox" ng-if="walletType=='digitalBitbox'">
<h4>
Digital Bitbox Hardware Wallet
BitBox Hardware Wallet
</h4>
<h5>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 79.536 79.536"><path fill="#5dba5a" d="M39.769 0C17.8 0 0 17.8 0 39.768c0 21.965 17.8 39.768 39.769 39.768 21.965 0 39.768-17.803 39.768-39.768C79.536 17.8 61.733 0 39.769 0zm-5.627 58.513L15.397 39.768l7.498-7.498 11.247 11.247 22.497-22.493 7.498 7.498-29.995 29.991z"/></svg>
Expand All @@ -424,31 +424,31 @@ <h5>
</div>
<ul>
<li class="u__protip">
<a href="https://digitalbitbox.com/ethereum"
<a href="https://shiftcrypto.ch/ethereum"
target="_blank"
rel="noopener noreferrer">
How to use Digital Bitbox with MyEtherWallet
How to use BitBox with MyEtherWallet
</a>
</li>
<li class="u__protip">
<a href="https://digitalbitbox.com/?ref=mew"
<a href="https://shiftcrypto.ch/?ref=mew"
target="_blank"
rel="noopener noreferrer">
Don't have a Digital Bitbox? Get one now.
Don't have a BitBox? Get one now.
</a>
</li>
</ul>
<input class="form-control"
aria-label="Enter the Digital Bitbox password"
aria-label="Enter the BitBox password"
aria-describedby="selectedTypeDigitalBitbox"
type="password"
placeholder="Digital Bitbox password"
placeholder="BitBox password"
spellcheck="false"
value=""
ng-model="HDWallet.digitalBitboxSecret" />
<div class="form-group">
<a tabindex="0" role="button" class="btn btn-primary" ng-click="scanDigitalBitbox()" translate="ADD_DigitalBitbox_scan">
Connect your Digital Bitbox
Connect your BitBox
</a>
</div>
</div>
Expand Down Expand Up @@ -873,7 +873,7 @@ <h4 id="modalTitle" class="modal-title" translate="ADD_Radio_5_Path" style="marg
value="{{HDWallet.defaultDPath}}"/>
<span ng-bind="HDWallet.defaultDPath"></span>
<p class="small">
Jaxx, Metamask, Exodus, imToken, TREZOR (ETH) &amp; Digital Bitbox
Jaxx, Metamask, Exodus, imToken, TREZOR (ETH) &amp; BitBox
</p>
</label>
</div>
Expand Down
169 changes: 99 additions & 70 deletions app/scripts/staticJS/digitalBitboxEth.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,46 @@ var DigitalBitboxEth = function(comm, sec) {
DigitalBitboxEth.to = setTimeout(function(){ DigitalBitboxEth.sec = ''; }, 60000);
}

var BitBoxSupportedMajorVersion = 5;

DigitalBitboxEth.sec = '';
DigitalBitboxEth.to = null;

DigitalBitboxEth.aes_cbc_b64_decrypt = function(ciphertext, key) {
var res;
try {
var h = Crypto.createHash('sha512').update(key).digest();
var encryptionKey = h.slice(0, 32);
var authenticationKey = h.slice(32, 64);

var ub64 = new Buffer(ciphertext, "base64").toString("binary");
var iv = new Buffer(ub64.slice(0, 16), "binary");
var enc = new Buffer(ub64.slice(16), "binary");
var decipher = Crypto.createDecipheriv("aes-256-cbc", key, iv);
var cipher = new Buffer(ub64.slice(0, ub64.length - 32), "binary");
var hmac = new Buffer(ub64.slice(ub64.length - 32), "binary");
var expectedHmac = Crypto.createHmac('sha256', authenticationKey).update(cipher).digest();
if (!hmac.equals(expectedHmac)) {
throw "hmac check failed";
}
var iv = new Buffer(cipher.slice(0, 16), "binary");
var enc = new Buffer(cipher.slice(16), "binary");
var decipher = Crypto.createDecipheriv("aes-256-cbc", encryptionKey, iv);
var dec = decipher.update(enc) + decipher.final();
res = dec.toString("utf8");
return dec.toString("utf8");
}
catch(err) {
res = ciphertext;
return ciphertext;
}
return res;
}

DigitalBitboxEth.aes_cbc_b64_encrypt = function(plaintext, key) {
try {
var h = Crypto.createHash('sha512').update(key).digest();
var encryptionKey = h.slice(0, 32);
var authenticationKey = h.slice(32, 64);

var iv = Crypto.pseudoRandomBytes(16);
var cipher = Crypto.createCipheriv("aes-256-cbc", key, iv);
var cipher = Crypto.createCipheriv("aes-256-cbc", encryptionKey, iv);
var ciphertext = Buffer.concat([iv, cipher.update(plaintext), cipher.final()]);
return ciphertext.toString("base64");
var hmac = Crypto.createHmac('sha256', authenticationKey).update(ciphertext).digest();
return Buffer.concat([ciphertext, hmac]).toString("base64");
}
catch(err) {
return '';
Expand All @@ -55,25 +70,48 @@ DigitalBitboxEth.aes_cbc_b64_encrypt = function(plaintext, key) {

DigitalBitboxEth.parseError = function(errObject) {
var errMsg = {
err101: 'The Digital Bitbox is not initialized. First use the <a href="https://digitalbitbox.com/start" target="_blank" rel="noopener noreferrer">Digital Bitbox desktop app</a> to set up a wallet.',// No password set
err250: 'The Digital Bitbox is not initialized. First use the <a href="https://digitalbitbox.com/start" target="_blank" rel="noopener noreferrer">Digital Bitbox desktop app</a> to set up a wallet.',// Wallet not seeded
err251: 'The Digital Bitbox is not initialized. First use the <a href="https://digitalbitbox.com/start" target="_blank" rel="noopener noreferrer">Digital Bitbox desktop app</a> to set up a wallet.',// Wallet not seeded
err109: 'The Digital Bitbox received unexpected data. Was the correct password used? ' + errObject.message,
err101: 'The BitBox is not initialized. First use the <a href="https://shiftcrypto.ch/start" target="_blank" rel="noopener noreferrer">Digital Bitbox desktop app</a> to set up a wallet.',// No password set
err250: 'The BitBox is not initialized. First use the <a href="https://shiftcrypto.ch/start" target="_blank" rel="noopener noreferrer">BitBox desktop app</a> to set up a wallet.',// Wallet not seeded
err251: 'The BitBox is not initialized. First use the <a href="https://shiftcrypto.ch/start" target="_blank" rel="noopener noreferrer">BitBox desktop app</a> to set up a wallet.',// Wallet not seeded
err109: 'The BitBox received unexpected data. Was the correct password used? ' + errObject.message,
};
var code = 'err' + errObject.code.toString();
var msg = errMsg[code] || errObject.message;
return msg;
}

DigitalBitboxEth.prototype.getAddress = function(path, callback) {
DigitalBitboxEth.prototype.send = function(cmd, callback) {
var self = this;
var cmd = '{"xpub":"' + path + '"}';
cmd = DigitalBitboxEth.aes_cbc_b64_encrypt(cmd, this.key);
var localCallback = function(response, error) {
if (typeof error != "undefined") {
callback(undefined, error);
}
else {

this.comm.exchange('{"ping":""}', function(pingResponse, pingError) {
if (typeof pingError !== 'undefined') {
callback(undefined, pingError);
return;
}
pingResponse = JSON.parse(pingResponse.toString('utf8'));
if (!('device' in pingResponse)) {
callback(undefined, 'Please upgrade to the newest firmware using the <a href="https://shiftcrypto.ch/start" target="_blank">BitBox Desktop app.</a>');
return;
}
var match = (/^v(\d+)\.\d+\.\d+/).exec(pingResponse.device.version);
if (match === null || match.length != 2) {
throw 'unexpected reply';
}
var majorVersion = parseInt(match[1]);
if (majorVersion < BitBoxSupportedMajorVersion) {
callback(undefined, 'Please upgrade to the newest firmware using the <a href="https://shiftcrypto.ch/start" target="_blank">BitBox Desktop app.</a>');
return;
}
if (majorVersion > BitBoxSupportedMajorVersion) {
callback(undefined, 'MyEtherWallet does not yet support this version of the firmware');
return;
}
var cipher = DigitalBitboxEth.aes_cbc_b64_encrypt(cmd, self.key)
self.comm.exchange(cipher, function(response, error) {
if (typeof pingError !== 'undefined') {
callback(undefined, pingError);
return;
}
try {
response = JSON.parse(response.toString('utf8'));
if ('error' in response) {
Expand All @@ -86,71 +124,62 @@ DigitalBitboxEth.prototype.getAddress = function(path, callback) {
callback(undefined, DigitalBitboxEth.parseError(response.error));
return;
}
var hdkey = HDKey.fromExtendedKey(response.xpub);
var result = {
publicKey: hdkey.publicKey.toString('hex'),
chainCode: hdkey.chainCode.toString('hex'),
};
callback(result);
return;
callback(response, undefined);
}
}
catch(err) {
callback(undefined, 'Unexpected error: ' + err.message);
}
});
});
}

DigitalBitboxEth.prototype.getAddress = function(path, callback) {
var self = this;
var cmd = '{"xpub":"' + path + '"}';
var localCallback = function(response, error) {
if (typeof error != "undefined") {
callback(undefined, error);
return;
}
var hdkey = HDKey.fromExtendedKey(response.xpub);
var result = {
publicKey: hdkey.publicKey.toString('hex'),
chainCode: hdkey.chainCode.toString('hex'),
};
callback(result);
return;
};
self.comm.exchange(cmd, localCallback);
self.send(cmd, localCallback);
}

DigitalBitboxEth.signGeneric = function(self, path, chainId, hashToSign, callback) {
var cmd = '{"sign":{"data":[{"hash":"' + hashToSign + '","keypath":"' + path + '"}]}}';
cmd = DigitalBitboxEth.aes_cbc_b64_encrypt(cmd, self.key);

var localCallback = function(response, error) {
if (typeof error != "undefined") {
callback(undefined, error);
return;
}
else {
try {
response = JSON.parse(response.toString('utf8'));
if ('error' in response) {
callback(undefined, DigitalBitboxEth.parseError(response.error));
return;
}
if ('ciphertext' in response) {
response = JSON.parse(DigitalBitboxEth.aes_cbc_b64_decrypt(response.ciphertext, self.key));
if ('error' in response) {
callback(undefined, DigitalBitboxEth.parseError(response.error));
return;
}
if ('echo' in response) {
// Echo from first sign command. (Smart verification not implemented.)
// Send second sign command.
var cmd = '{"sign":""}';
cmd = DigitalBitboxEth.aes_cbc_b64_encrypt(cmd, self.key);
self.comm.exchange(cmd, localCallback);
return;
}
if ('sign' in response) {
var vOffset = chainId ? chainId * 2 + 8 : 0;
var v = new Buffer([parseInt(response.sign[0].recid, 16) + 27 + vOffset]);
var result = {
v: v.toString('hex'),
r: response.sign[0].sig.slice(0, 64),
s: response.sign[0].sig.slice(64, 128),
};
callback(result);
return;
}
}
}
catch(err) {
callback(undefined, 'Unexpected error:' + err.message);
}
}
if ('echo' in response) {
// Echo from first sign command. (Smart verification not implemented.)
// Send second sign command.
var cmd = '{"sign":""}';
self.send(cmd, localCallback);
return;
}
if ('sign' in response) {
var vOffset = chainId ? chainId * 2 + 8 : 0;
var v = new Buffer([parseInt(response.sign[0].recid, 16) + 27 + vOffset]);
var result = {
v: v.toString('hex'),
r: response.sign[0].sig.slice(0, 64),
s: response.sign[0].sig.slice(64, 128),
};
callback(result);
return;
}
};
self.comm.exchange(cmd, localCallback);
self.send(cmd, localCallback);
}

DigitalBitboxEth.prototype.signTransaction = function(path, eTx, callback) {
Expand Down
4 changes: 2 additions & 2 deletions app/scripts/translations/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ ONBOARD_resume : 'It looks like you didn\'t finish reading thr
/* Old */
ADD_DigitalBitbox_0a : 'Re-open MyEtherWallet on a secure (SSL) connection',
ADD_DigitalBitbox_0b : 'Re-open MyEtherWallet using [Chrome](https://www.google.com/chrome/browser/desktop/) or [Opera](https://www.opera.com/)',
ADD_DigitalBitbox_scan : 'Connect your Digital Bitbox',
ADD_DigitalBitbox_scan : 'Connect your BitBox',
ADD_Secalot_0a : 'Re-open MyEtherWallet on a secure (SSL) connection ',
ADD_Secalot_0b : 'Re-open MyEtherWallet using [Chrome](https://www.google.com/chrome/browser/desktop/) or [Opera](https://www.opera.com/) ',
ADD_Secalot_scan : 'Connect your Secalot ',
Expand Down Expand Up @@ -580,7 +580,7 @@ x_Cancel : 'Cancel',
x_CancelReplaceTx : 'Cancel or Replace Transaction',
x_CancelTx : 'Cancel Transaction',
x_CSV : 'CSV file (unencrypted)',
x_DigitalBitbox : 'Digital Bitbox',
x_DigitalBitbox : 'BitBox',
x_Secalot : 'Secalot ',
x_Download : 'Download',
x_Json : 'JSON File (unencrypted)',
Expand Down