Example #1
0
 def connect(self):
     """Enumerate and connect to the first USB HID interface."""
     try:
         return comm.getDongle()
     except comm.CommException as e:
         raise interface.NotFoundError(
             '{} not connected: "{}"'.format(self, e))
Example #2
0
def handleSignRequest(message, key, eddsa, path):
	logging.debug("Sign request")
	blobSize = struct.unpack(">I", message[0:4])[0]
	blob = message[4 : 4 + blobSize]
	if blob <> key:
		logging.debug("Client sent a different blob " + blob.encode('hex'))
		return chr(SSH_AGENT_FAILURE)
	challengeSize = struct.unpack(">I", message[4 + blobSize : 4 + blobSize + 4])[0]
	challenge = message[4 + blobSize + 4: 4 + blobSize + 4 + challengeSize]
	# Send the challenge in chunks
	dongle = getDongle(logging.getLogger().isEnabledFor(logging.DEBUG))
	donglePath = parse_bip32_path(args.path)
	offset = 0
	while offset <> len(challenge):
		data = ""
		if offset == 0:
			donglePath = parse_bip32_path(path)
			data = chr(len(donglePath) / 4) + donglePath
		if (len(challenge) - offset) > (255 - len(data)):
			chunkSize = (255 - len(data))
		else:
			chunkSize = len(challenge) - offset
		data += challenge[offset : offset + chunkSize]
		if offset == 0:
			p1 = 0x00
		else:
			p1 = 0x01
		if eddsa:
			p2 = 0x02
		else:
			p2 = 0x01
		offset += chunkSize
		apdu = "8004".decode('hex') + chr(p1) + chr(p2) + chr(len(data)) + data
		signature = dongle.exchange(bytes(apdu))
	dongle.close()
	# Parse r and s
	rLength = signature[3]
	r = signature[4 : 4 + rLength]
	sLength = signature[4 + rLength + 1]
	s = signature[4 + rLength + 2:]
	r = str(r)
	s = str(s)

	encodedSignatureValue = struct.pack(">I", len(r)) + r
	encodedSignatureValue += struct.pack(">I", len(s)) + s

	encodedSignature = struct.pack(">I", len(SIG_HEADER)) + SIG_HEADER
	encodedSignature += struct.pack(">I", len(encodedSignatureValue)) + encodedSignatureValue

	response = chr(SSH2_AGENT_SIGN_RESPONSE)

	response += struct.pack(">I", len(encodedSignature)) + encodedSignature
	return response
if args.path == None:
	args.path = "44'/535348'/0'/0/0"

if args.ed25519:
	p2 = "02"
	keyHeader = KEY_HEADER_ED25519
else:
	p2 = "01" 
	keyHeader = KEY_HEADER

donglePath = parse_bip32_path(args.path)
apdu = "800200" + p2 
apdu = apdu.decode('hex') + chr(len(donglePath) + 1) + chr(len(donglePath) / 4) + donglePath

dongle = getDongle(True)
result = dongle.exchange(bytes(apdu))
key = str(result[1:])
blob = struct.pack(">I", len(KEY_HEADER)) + keyHeader 
if args.ed25519:
	keyX = bytearray(key[0:32])
	keyY = bytearray(key[32:][::-1])
	if ((keyX[31] & 1)<>0):
		keyY[31] |= 0x80
	key = str(keyY)
else:
	blob += struct.pack(">I", len(CURVE_NAME)) + CURVE_NAME
	
blob += struct.pack(">I", len(key)) + key
print keyHeader + " " + base64.b64encode(blob)
*
*  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.
********************************************************************************
"""

from ledgerblue.comm import getDongle
import argparse

def auto_int(x):
    return int(x, 0)

parser = argparse.ArgumentParser()
parser.add_argument("--fileName", help="Set the file name to load")
parser.add_argument("--apdu", help="Display APDU log", action='store_true')

args = parser.parse_args()

if args.fileName == None:
	raise Exception("Missing fileName")

dongle = getDongle(args.apdu)
file = open(args.fileName, "r")
for data in file:
	data = data.rstrip('\r\n').decode('hex')
	dongle.exchange(bytearray(data))	

Example #5
0
    import struct

    path = args.from_addr
    donglePath = b''
    for pathElement in path.split('/'):
        element = pathElement.split('\'')
        if len(element) == 1:
            donglePath += struct.pack(">I", int(element[0]))
        else:
            donglePath += struct.pack(">I", 0x80000000 | int(element[0]))
    apdu =  bytes.fromhex('e0020000')
    apdu += bytes([len(donglePath) + 1])
    apdu += bytes([len(donglePath) // 4])
    apdu += donglePath

    result = getDongle(True).exchange(apdu)
    offset = 1 + result[0]
    address = result[offset + 1 : offset + 1 + result[offset]]
    from_addr = "0x" + str(address.decode('ascii')).lower()

if args.keytype == 'file':
    from_addr = args.from_addr

# Check address validity
if not web3.isAddress(from_addr):
    raise Exception('Invalid address %s' % from_addr)
if not web3.isAddress(args.to_addr):
    raise Exception('Invalid address %s' % args.to_addr)

# Fetch nonce from the blockchain
if args.nonce < 0:
Example #6
0
parser.add_argument("--apdu", help="Display APDU log", action='store_true')
parser.add_argument("--perso", help="Personalization key reference to use")
parser.add_argument("--firmware", help="Firmware reference to use")
parser.add_argument("--firmwareKey", help="Firmware reference key to use")

args = parser.parse_args()
if args.url == None:
    raise Exception("No URL specified")
if args.perso == None:
    raise Exception("No personalization specified")
if args.firmware == None:
    raise Exception("No firmware specified")
if args.firmwareKey == None:
    raise Exception("No firmware key specified")

dongle = getDongle(args.apdu)

# Identify

targetid = bytearray(struct.pack('>I', 0x31000001))
apdu = bytearray([0xe0, 0x04, 0x00, 0x00]) + bytearray([len(targetid)
                                                        ]) + targetid
dongle.exchange(apdu)

# Initialize chain

dongle.exchange(bytearray.fromhex('E050000000'))

# Get remote certificate

request = Request()
Example #7
0
def clear_online_seed(lang):
    print("Open device...")
    dongle = getDongle(False)

    print("Erase old key words...")
    dongle.exchange(pack('>6B', 0x00, 0x28, 0x02, 0x00, 0x01, 0x00))
Example #8
0
try:
    # Send the APDU Payloads in (N)Chunks
    for i in range(chunkCount):
        if chunks[i] is not None:
            hasMoreChunks = chunks[i + 1] is not None
            p1 = p1_single if chunkCount == 1               \
                else p1_first if i == 0 and hasMoreChunks   \
                else p1_more if hasMoreChunks else p1_last
            apdu = bytearray.fromhex(cla + operation + p1 + p2)

            if i == 0:
                apdu.append(pathLength + len(chunks[0]))
                apdu.append(pathLength // 4)
                apdu += donglePath + chunks[0]
                dongle = getDongle(True)
            else:
                apdu.append(len(chunks[i]))
                apdu += chunks[i]

            result = dongle.exchange(bytes(apdu))

            if len(result) == 0:
                print("Sending next APDU Chunk..")
            else:
                print(
                    "\nPayload:",
                    binascii.hexlify(payload).decode("utf-8")
                )
                print("\nApproved by user on Path:", args.path, "\n")
                print(
Example #9
0
def exchange(apdu):
    dongle = getDongle(True)
    return dongle.exchange(apdu)
Example #10
0
 def __enter__(self):
     self.d = getDongle(debug=DEBUG)
     return self.d
Example #11
0
def point_mul(P, n):
    R = None
    for i in range(N):
        if ((n >> i) & 1):
            R = point_add(R, P)
        P = point_add(P, P)
    return R

textToSign = b''
while True:
        data = input('Enter text to sign, end with an empty line : ')
        if len(data) == 0:
                break
        textToSign += data.encode() + b'\n'

dongle = getDongle(True) # True here means debug is on

try:
    publicKey = dongle.exchange(bytes.fromhex('8004000000'))
except:
    if comm.sw == 0x6804:
        raise RuntimeError('Invalid status from Ledger: %x. Is the device unlocked?' % comm.sw)
print('publicKey ', publicKey.hex())

try:
        offset = 0
        while offset != len(textToSign):
                if (len(textToSign) - offset) > 255:
                        chunk = textToSign[offset : offset + 255]
                else:
                        chunk = textToSign[offset:]
Example #12
0
def get_dongle():
    global dongle
    if dongle is None:
        dongle = getDongle(True)
    return dongle
from ledgerblue.comm import getDongle
from tx_pb2 import Transaction
import struct

input_1 = Transaction.Input(input_tx_hash=bytes.fromhex(
    "ac3c7f1938e9bb4e04f296eb7b1d13758e904dcecf352bc5349eda43c84ebbc6"),
                            input_index=0)
output_0 = Transaction.Output(dest_addr=bytes.fromhex(
    "05c829a6b0ec3df93dac8c07d6b947ee99c4ff103d1b303894"),
                              amount=79798)
message = "https://bit.ly/32hI7ly"

tx = Transaction(inputs=[input_1, input_1, input_1, input_1],
                 outputs=[output_0, output_0, output_0, output_0, output_0],
                 msg=message)

# prefix buffer with its size
request = struct.pack(">H", len(
    tx.SerializeToString())) + tx.SerializeToString()

dongle = getDongle(debug=True)

apdu = bytes.fromhex("e0020000")
chunkSize = 200

for chunk in [
        request[i:i + chunkSize] for i in range(0, len(request), chunkSize)
]:
    capdu = apdu + struct.pack('B', len(chunk)) + chunk
    response = dongle.exchange(bytes(capdu))
    apdu = apdu[:2] + struct.pack('B', apdu[2] | 0x80) + apdu[3:]
Example #14
0
import ed25519
import msgpack
import base64
import sha512_256
import sys
import os
import struct
import algomsgpack


def checksummed(pk):
    sum = sha512_256.new(str(pk)).digest()
    return base64.b32encode(pk + sum[28:32]).replace("=", "")


dongle = getDongle(debug=False)

publicKey = dongle.exchange(bytes("8003000000".decode('hex')))
print "Ledger app address:", checksummed(publicKey)

if len(sys.argv) != 3:
    print "Usage: %s infile outfile" % sys.argv[0]
    sys.exit(0)

(_, infile, outfile) = sys.argv

with open(infile) as f:
    buf = f.read()
    instx = msgpack.unpackb(buf, raw=False)
    intx = instx['txn']
Example #15
0
 def __init__(self):
     self.dongle = getDongle(debug=False)