@ledgerhq/hw-app-str
Advanced tools
Comparing version 4.13.0 to 4.14.0
@@ -1,3 +0,3 @@ | ||
// flow-typed signature: de76e43b7f594cd142bb9865fb4eb16a | ||
// flow-typed version: <<STUB>>/@ledgerhq/hw-transport_v^4.7.3/flow_v0.68.0 | ||
// flow-typed signature: a6d424443969ff4bc7162d7f7bad024e | ||
// flow-typed version: <<STUB>>/@ledgerhq/hw-transport_v^4.13.0/flow_v0.68.0 | ||
@@ -4,0 +4,0 @@ /** |
@@ -40,2 +40,3 @@ "use strict"; | ||
var INS_SIGN_TX_HASH = 0x08; | ||
var INS_KEEP_ALIVE = 0x10; | ||
@@ -52,5 +53,8 @@ var APDU_MAX_SIZE = 150; | ||
var SW_MULTI_OP = 0x6c25; | ||
var SW_SAFE_MODE = 0x6c66; | ||
var SW_NOT_ALLOWED = 0x6c66; | ||
var SW_UNSUPPORTED = 0x6d00; | ||
var SW_KEEP_ALIVE = 0x6e02; | ||
var TX_MAX_SIZE = 1540; | ||
/** | ||
@@ -98,2 +102,9 @@ * Stellar API | ||
value: function getPublicKey(path, boolValidate, boolDisplay) { | ||
var _this = this; | ||
(0, _utils.checkStellarBip32Path)(path); | ||
var apdus = []; | ||
var response = void 0; | ||
var pathElts = (0, _utils.splitPath)(path); | ||
@@ -106,4 +117,14 @@ var buffer = new Buffer(1 + pathElts.length * 4); | ||
var verifyMsg = Buffer.from("via lumina", "ascii"); | ||
buffer = Buffer.concat([buffer, verifyMsg]); | ||
return this.transport.send(CLA, INS_GET_PK, boolValidate ? 0x01 : 0x00, boolDisplay ? 0x01 : 0x00, buffer).then(function (response) { | ||
apdus.push(Buffer.concat([buffer, verifyMsg])); | ||
var keepAlive = false; | ||
return (0, _utils.foreach)(apdus, function (data) { | ||
return _this.transport.send(CLA, keepAlive ? INS_KEEP_ALIVE : INS_GET_PK, boolValidate ? 0x01 : 0x00, boolDisplay ? 0x01 : 0x00, data, [SW_OK, SW_KEEP_ALIVE]).then(function (apduResponse) { | ||
var status = Buffer.from(apduResponse.slice(apduResponse.length - 2)).readUInt16BE(0); | ||
if (status === SW_KEEP_ALIVE) { | ||
keepAlive = true; | ||
apdus.push(Buffer.alloc(0)); | ||
} | ||
response = apduResponse; | ||
}); | ||
}).then(function () { | ||
// response = Buffer.from(response, 'hex'); | ||
@@ -138,6 +159,10 @@ var offset = 0; | ||
value: function signTransaction(path, transaction) { | ||
var _this = this; | ||
var _this2 = this; | ||
(0, _utils.checkStellarBip32Path)(path); | ||
if (transaction.length > TX_MAX_SIZE) { | ||
throw new Error("Transaction too large: max = " + TX_MAX_SIZE + "; actual = " + transaction.length); | ||
} | ||
var apdus = []; | ||
@@ -173,4 +198,10 @@ var response = void 0; | ||
} | ||
var keepAlive = false; | ||
return (0, _utils.foreach)(apdus, function (data, i) { | ||
return _this.transport.send(CLA, INS_SIGN_TX, i === 0 ? P1_FIRST_APDU : P1_MORE_APDU, i === apdus.length - 1 ? P2_LAST_APDU : P2_MORE_APDU, data, [SW_OK, SW_CANCEL, SW_UNKNOWN_OP, SW_MULTI_OP]).then(function (apduResponse) { | ||
return _this2.transport.send(CLA, keepAlive ? INS_KEEP_ALIVE : INS_SIGN_TX, i === 0 ? P1_FIRST_APDU : P1_MORE_APDU, i === apdus.length - 1 ? P2_LAST_APDU : P2_MORE_APDU, data, [SW_OK, SW_CANCEL, SW_UNKNOWN_OP, SW_MULTI_OP, SW_KEEP_ALIVE]).then(function (apduResponse) { | ||
var status = Buffer.from(apduResponse.slice(apduResponse.length - 2)).readUInt16BE(0); | ||
if (status === SW_KEEP_ALIVE) { | ||
keepAlive = true; | ||
apdus.push(Buffer.alloc(0)); | ||
} | ||
response = apduResponse; | ||
@@ -187,6 +218,6 @@ }); | ||
// pre-v2 app version: fall back on hash signing | ||
return _this.signHash_private(path, (0, _utils.hash)(transaction)); | ||
return _this2.signHash_private(path, (0, _utils.hash)(transaction)); | ||
} else if (status === SW_MULTI_OP) { | ||
// multi-operation transaction: attempt hash signing | ||
return _this.signHash_private(path, (0, _utils.hash)(transaction)); | ||
return _this2.signHash_private(path, (0, _utils.hash)(transaction)); | ||
} else { | ||
@@ -199,3 +230,2 @@ throw new Error("Transaction approval request was rejected"); | ||
/** | ||
* @deprecated | ||
* sign a Stellar transaction hash. | ||
@@ -212,2 +242,3 @@ * @param path a path in BIP 32 format | ||
value: function signHash(path, hash) { | ||
(0, _utils.checkStellarBip32Path)(path); | ||
return this.signHash_private(path, hash); | ||
@@ -218,2 +249,7 @@ } | ||
value: function signHash_private(path, hash) { | ||
var _this3 = this; | ||
var apdus = []; | ||
var response = void 0; | ||
var pathElts = (0, _utils.splitPath)(path); | ||
@@ -225,4 +261,14 @@ var buffer = Buffer.alloc(1 + pathElts.length * 4); | ||
}); | ||
buffer = Buffer.concat([buffer, hash]); | ||
return this.transport.send(CLA, INS_SIGN_TX_HASH, 0x00, 0x00, buffer, [SW_OK, SW_CANCEL, SW_SAFE_MODE, SW_UNSUPPORTED]).then(function (response) { | ||
apdus.push(Buffer.concat([buffer, hash])); | ||
var keepAlive = false; | ||
return (0, _utils.foreach)(apdus, function (data) { | ||
return _this3.transport.send(CLA, keepAlive ? INS_KEEP_ALIVE : INS_SIGN_TX_HASH, 0x00, 0x00, data, [SW_OK, SW_CANCEL, SW_NOT_ALLOWED, SW_UNSUPPORTED, SW_KEEP_ALIVE]).then(function (apduResponse) { | ||
var status = Buffer.from(apduResponse.slice(apduResponse.length - 2)).readUInt16BE(0); | ||
if (status === SW_KEEP_ALIVE) { | ||
keepAlive = true; | ||
apdus.push(Buffer.alloc(0)); | ||
} | ||
response = apduResponse; | ||
}); | ||
}).then(function () { | ||
var status = Buffer.from(response.slice(response.length - 2)).readUInt16BE(0); | ||
@@ -234,9 +280,8 @@ if (status === SW_OK) { | ||
}; | ||
} | ||
if (status === SW_SAFE_MODE) { | ||
throw new Error("To sign multi-operation transactions 'Unsafe mode' must be enabled in the app settings"); | ||
} else if (status === SW_CANCEL) { | ||
throw new Error("Transaction approval request was rejected"); | ||
} else if (status === SW_UNSUPPORTED) { | ||
throw new Error("Multi-operation transactions are not supported"); | ||
throw new Error("Hash signing is not supported"); | ||
} else { | ||
throw new Error("Transaction approval request was rejected"); | ||
throw new Error("Hash signing not allowed. Have you enabled it in the app settings?"); | ||
} | ||
@@ -243,0 +288,0 @@ }); |
@@ -13,2 +13,3 @@ "use strict"; | ||
exports.foreach = foreach; | ||
exports.crc16xmodem = crc16xmodem; | ||
exports.encodeEd25519PublicKey = encodeEd25519PublicKey; | ||
@@ -19,6 +20,2 @@ exports.verifyEd25519Signature = verifyEd25519Signature; | ||
var _crc16_xmodem = require("crc/lib/crc16_xmodem"); | ||
var _crc16_xmodem2 = _interopRequireDefault(_crc16_xmodem); | ||
var _base = require("base32.js"); | ||
@@ -37,18 +34,2 @@ | ||
// TODO use bip32-path library | ||
/******************************************************************************** | ||
* Ledger Node JS API | ||
* (c) 2017-2018 Ledger | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
********************************************************************************/ | ||
function splitPath(path) { | ||
@@ -68,4 +49,20 @@ var result = []; | ||
return result; | ||
} | ||
} /******************************************************************************** | ||
* Ledger Node JS API | ||
* (c) 2017-2018 Ledger | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
********************************************************************************/ | ||
function foreach(arr, callback) { | ||
@@ -87,2 +84,22 @@ function iterate(index, array, result) { | ||
function crc16xmodem(buf, previous) { | ||
var crc = typeof previous !== "undefined" ? ~~previous : 0x0; | ||
for (var index = 0; index < buf.length; index++) { | ||
var byte = buf[index]; | ||
var code = crc >>> 8 & 0xff; | ||
code ^= byte & 0xff; | ||
code ^= code >>> 4; | ||
crc = crc << 8 & 0xffff; | ||
crc ^= code; | ||
code = code << 5 & 0xffff; | ||
crc ^= code; | ||
code = code << 7 & 0xffff; | ||
crc ^= code; | ||
} | ||
return crc; | ||
} | ||
function encodeEd25519PublicKey(rawPublicKey) { | ||
@@ -94,3 +111,3 @@ var versionByte = 6 << 3; // 'G' | ||
var checksum = Buffer.alloc(2); | ||
checksum.writeUInt16LE((0, _crc16_xmodem2.default)(payload), 0); | ||
checksum.writeUInt16LE(crc16xmodem(payload), 0); | ||
var unencoded = Buffer.concat([payload, checksum]); | ||
@@ -97,0 +114,0 @@ return _base2.default.encode(unencoded); |
{ | ||
"name": "@ledgerhq/hw-app-str", | ||
"version": "4.13.0", | ||
"version": "4.14.0", | ||
"description": "Ledger Hardware Wallet Stellar Application API", | ||
@@ -30,3 +30,2 @@ "keywords": [ | ||
"base32.js": "^0.1.0", | ||
"crc": "^3.5.0", | ||
"sha.js": "^2.3.6", | ||
@@ -33,0 +32,0 @@ "tweetnacl": "^1.0.0" |
169
src/Str.js
@@ -34,2 +34,3 @@ /******************************************************************************** | ||
const INS_SIGN_TX_HASH = 0x08; | ||
const INS_KEEP_ALIVE = 0x10; | ||
@@ -46,5 +47,8 @@ const APDU_MAX_SIZE = 150; | ||
const SW_MULTI_OP = 0x6c25; | ||
const SW_SAFE_MODE = 0x6c66; | ||
const SW_NOT_ALLOWED = 0x6c66; | ||
const SW_UNSUPPORTED = 0x6d00; | ||
const SW_KEEP_ALIVE = 0x6e02; | ||
const TX_MAX_SIZE = 1540; | ||
/** | ||
@@ -96,2 +100,7 @@ * Stellar API | ||
): Promise<{ publicKey: string }> { | ||
checkStellarBip32Path(path); | ||
let apdus = []; | ||
let response; | ||
let pathElts = splitPath(path); | ||
@@ -104,29 +113,42 @@ let buffer = new Buffer(1 + pathElts.length * 4); | ||
let verifyMsg = Buffer.from("via lumina", "ascii"); | ||
buffer = Buffer.concat([buffer, verifyMsg]); | ||
return this.transport | ||
.send( | ||
CLA, | ||
INS_GET_PK, | ||
boolValidate ? 0x01 : 0x00, | ||
boolDisplay ? 0x01 : 0x00, | ||
buffer | ||
) | ||
.then(response => { | ||
// response = Buffer.from(response, 'hex'); | ||
let offset = 0; | ||
let rawPublicKey = response.slice(offset, offset + 32); | ||
offset += 32; | ||
let publicKey = encodeEd25519PublicKey(rawPublicKey); | ||
if (boolValidate) { | ||
let signature = response.slice(offset, offset + 64); | ||
if (!verifyEd25519Signature(verifyMsg, signature, rawPublicKey)) { | ||
throw new Error( | ||
"Bad signature. Keypair is invalid. Please report this." | ||
); | ||
apdus.push(Buffer.concat([buffer, verifyMsg])); | ||
let keepAlive = false; | ||
return foreach(apdus, data => | ||
this.transport | ||
.send( | ||
CLA, | ||
keepAlive ? INS_KEEP_ALIVE : INS_GET_PK, | ||
boolValidate ? 0x01 : 0x00, | ||
boolDisplay ? 0x01 : 0x00, | ||
data, | ||
[SW_OK, SW_KEEP_ALIVE] | ||
) | ||
.then(apduResponse => { | ||
let status = Buffer.from( | ||
apduResponse.slice(apduResponse.length - 2) | ||
).readUInt16BE(0); | ||
if (status === SW_KEEP_ALIVE) { | ||
keepAlive = true; | ||
apdus.push(Buffer.alloc(0)); | ||
} | ||
response = apduResponse; | ||
}) | ||
).then(() => { | ||
// response = Buffer.from(response, 'hex'); | ||
let offset = 0; | ||
let rawPublicKey = response.slice(offset, offset + 32); | ||
offset += 32; | ||
let publicKey = encodeEd25519PublicKey(rawPublicKey); | ||
if (boolValidate) { | ||
let signature = response.slice(offset, offset + 64); | ||
if (!verifyEd25519Signature(verifyMsg, signature, rawPublicKey)) { | ||
throw new Error( | ||
"Bad signature. Keypair is invalid. Please report this." | ||
); | ||
} | ||
return { | ||
publicKey: publicKey | ||
}; | ||
}); | ||
} | ||
return { | ||
publicKey: publicKey | ||
}; | ||
}); | ||
} | ||
@@ -148,2 +170,11 @@ | ||
if (transaction.length > TX_MAX_SIZE) { | ||
throw new Error( | ||
"Transaction too large: max = " + | ||
TX_MAX_SIZE + | ||
"; actual = " + | ||
transaction.length | ||
); | ||
} | ||
let apdus = []; | ||
@@ -179,2 +210,3 @@ let response; | ||
} | ||
let keepAlive = false; | ||
return foreach(apdus, (data, i) => | ||
@@ -184,9 +216,16 @@ this.transport | ||
CLA, | ||
INS_SIGN_TX, | ||
keepAlive ? INS_KEEP_ALIVE : INS_SIGN_TX, | ||
i === 0 ? P1_FIRST_APDU : P1_MORE_APDU, | ||
i === apdus.length - 1 ? P2_LAST_APDU : P2_MORE_APDU, | ||
data, | ||
[SW_OK, SW_CANCEL, SW_UNKNOWN_OP, SW_MULTI_OP] | ||
[SW_OK, SW_CANCEL, SW_UNKNOWN_OP, SW_MULTI_OP, SW_KEEP_ALIVE] | ||
) | ||
.then(apduResponse => { | ||
let status = Buffer.from( | ||
apduResponse.slice(apduResponse.length - 2) | ||
).readUInt16BE(0); | ||
if (status === SW_KEEP_ALIVE) { | ||
keepAlive = true; | ||
apdus.push(Buffer.alloc(0)); | ||
} | ||
response = apduResponse; | ||
@@ -216,3 +255,2 @@ }) | ||
/** | ||
* @deprecated | ||
* sign a Stellar transaction hash. | ||
@@ -226,2 +264,3 @@ * @param path a path in BIP 32 format | ||
signHash(path: string, hash: Buffer): Promise<{ signature: Buffer }> { | ||
checkStellarBip32Path(path); | ||
return this.signHash_private(path, hash); | ||
@@ -231,2 +270,5 @@ } | ||
signHash_private(path: string, hash: Buffer): Promise<{ signature: Buffer }> { | ||
let apdus = []; | ||
let response; | ||
let pathElts = splitPath(path); | ||
@@ -238,31 +280,44 @@ let buffer = Buffer.alloc(1 + pathElts.length * 4); | ||
}); | ||
buffer = Buffer.concat([buffer, hash]); | ||
return this.transport | ||
.send(CLA, INS_SIGN_TX_HASH, 0x00, 0x00, buffer, [ | ||
SW_OK, | ||
SW_CANCEL, | ||
SW_SAFE_MODE, | ||
SW_UNSUPPORTED | ||
]) | ||
.then(response => { | ||
let status = Buffer.from( | ||
response.slice(response.length - 2) | ||
).readUInt16BE(0); | ||
if (status === SW_OK) { | ||
let signature = Buffer.from(response.slice(0, response.length - 2)); | ||
return { | ||
signature: signature | ||
}; | ||
} | ||
if (status === SW_SAFE_MODE) { | ||
throw new Error( | ||
"To sign multi-operation transactions 'Unsafe mode' must be enabled in the app settings" | ||
); | ||
} else if (status === SW_UNSUPPORTED) { | ||
throw new Error("Multi-operation transactions are not supported"); | ||
} else { | ||
throw new Error("Transaction approval request was rejected"); | ||
} | ||
}); | ||
apdus.push(Buffer.concat([buffer, hash])); | ||
let keepAlive = false; | ||
return foreach(apdus, data => | ||
this.transport | ||
.send( | ||
CLA, | ||
keepAlive ? INS_KEEP_ALIVE : INS_SIGN_TX_HASH, | ||
0x00, | ||
0x00, | ||
data, | ||
[SW_OK, SW_CANCEL, SW_NOT_ALLOWED, SW_UNSUPPORTED, SW_KEEP_ALIVE] | ||
) | ||
.then(apduResponse => { | ||
let status = Buffer.from( | ||
apduResponse.slice(apduResponse.length - 2) | ||
).readUInt16BE(0); | ||
if (status === SW_KEEP_ALIVE) { | ||
keepAlive = true; | ||
apdus.push(Buffer.alloc(0)); | ||
} | ||
response = apduResponse; | ||
}) | ||
).then(() => { | ||
let status = Buffer.from( | ||
response.slice(response.length - 2) | ||
).readUInt16BE(0); | ||
if (status === SW_OK) { | ||
let signature = Buffer.from(response.slice(0, response.length - 2)); | ||
return { | ||
signature: signature | ||
}; | ||
} else if (status === SW_CANCEL) { | ||
throw new Error("Transaction approval request was rejected"); | ||
} else if (status === SW_UNSUPPORTED) { | ||
throw new Error("Hash signing is not supported"); | ||
} else { | ||
throw new Error( | ||
"Hash signing not allowed. Have you enabled it in the app settings?" | ||
); | ||
} | ||
}); | ||
} | ||
} |
@@ -19,3 +19,2 @@ /******************************************************************************** | ||
import crc16xmodem from "crc/lib/crc16_xmodem"; | ||
import base32 from "base32.js"; | ||
@@ -59,2 +58,22 @@ import nacl from "tweetnacl"; | ||
export function crc16xmodem(buf: Buffer, previous?: number): number { | ||
let crc = typeof previous !== "undefined" ? ~~previous : 0x0; | ||
for (var index = 0; index < buf.length; index++) { | ||
const byte = buf[index]; | ||
let code = (crc >>> 8) & 0xff; | ||
code ^= byte & 0xff; | ||
code ^= code >>> 4; | ||
crc = (crc << 8) & 0xffff; | ||
crc ^= code; | ||
code = (code << 5) & 0xffff; | ||
crc ^= code; | ||
code = (code << 7) & 0xffff; | ||
crc ^= code; | ||
} | ||
return crc; | ||
} | ||
export function encodeEd25519PublicKey(rawPublicKey: Buffer): string { | ||
@@ -61,0 +80,0 @@ let versionByte = 6 << 3; // 'G' |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
83319
4
1195
17
- Removedcrc@^3.5.0
- Removedbase64-js@1.5.1(transitive)
- Removedbuffer@5.7.1(transitive)
- Removedcrc@3.8.0(transitive)
- Removedieee754@1.2.1(transitive)