Add scripts related to Nano S 1.3
This commit is contained in:
parent
310442593d
commit
09ad4fd1e2
|
@ -25,6 +25,8 @@ import hid
|
|||
import time
|
||||
import sys
|
||||
|
||||
TIMEOUT=20000
|
||||
|
||||
try:
|
||||
from smartcard.Exceptions import NoCardException
|
||||
from smartcard.System import readers
|
||||
|
@ -52,7 +54,7 @@ class Dongle(object):
|
|||
__metaclass__ = ABCMeta
|
||||
|
||||
@abstractmethod
|
||||
def exchange(self, apdu, timeout=20):
|
||||
def exchange(self, apdu, timeout=TIMEOUT):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
|
@ -71,7 +73,7 @@ class HIDDongleHIDAPI(Dongle, DongleWait):
|
|||
self.waitImpl = self
|
||||
self.opened = True
|
||||
|
||||
def exchange(self, apdu, timeout=20):
|
||||
def exchange(self, apdu, timeout=TIMEOUT):
|
||||
if self.debug:
|
||||
print("=> %s" % hexstr(apdu))
|
||||
if self.ledger:
|
||||
|
@ -155,7 +157,7 @@ class DongleSmartcard(Dongle):
|
|||
self.waitImpl = self
|
||||
self.opened = True
|
||||
|
||||
def exchange(self, apdu, timeout=20):
|
||||
def exchange(self, apdu, timeout=TIMEOUT):
|
||||
if self.debug:
|
||||
print("=> %s" % hexstr(apdu))
|
||||
response, sw1, sw2 = self.device.transmit(toBytes(hexlify(apdu)))
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
"""
|
||||
*******************************************************************************
|
||||
* Ledger Blue
|
||||
* (c) 2016 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.
|
||||
********************************************************************************
|
||||
"""
|
||||
|
||||
DEFAULT_ALIGNMENT = 1024
|
||||
|
||||
from .ecWrapper import PrivateKey
|
||||
from .comm import getDongle
|
||||
from .hexParser import IntelHexParser, IntelHexPrinter
|
||||
from .hexLoader import HexLoader
|
||||
from .deployed import getDeployedSecretV1, getDeployedSecretV2
|
||||
import argparse
|
||||
import struct
|
||||
import binascii
|
||||
import sys
|
||||
|
||||
privateKey = PrivateKey()
|
||||
publicKey = binascii.hexlify(privateKey.pubkey.serialize(compressed=False))
|
||||
print("Public key : %s" % publicKey)
|
||||
print("Private key: %s" % privateKey.serialize())
|
|
@ -226,3 +226,12 @@ class HexLoader:
|
|||
initialAddress = hexFile.minAddr()
|
||||
self.boot(bootaddr - initialAddress, signature)
|
||||
|
||||
def resetCustomCA(self):
|
||||
data = b'\x13'
|
||||
data = self.encryptAES(data)
|
||||
self.exchange(self.cla, 0x00, 0x00, 0x00, data)
|
||||
|
||||
def setupCustomCA(self, name, public):
|
||||
data = b'\x12' + struct.pack('>B',len(name)) + name + struct.pack('>B',len(public)) + public
|
||||
data = self.encryptAES(data)
|
||||
self.exchange(self.cla, 0x00, 0x00, 0x00, data)
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
"""
|
||||
*******************************************************************************
|
||||
* Ledger Blue
|
||||
* (c) 2016 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.
|
||||
********************************************************************************
|
||||
"""
|
||||
|
||||
DEFAULT_ALIGNMENT = 1024
|
||||
|
||||
from .ecWrapper import PrivateKey
|
||||
from .comm import getDongle
|
||||
from .hexParser import IntelHexParser, IntelHexPrinter
|
||||
from .hexLoader import HexLoader
|
||||
import argparse
|
||||
import struct
|
||||
import binascii
|
||||
import sys
|
||||
import getpass
|
||||
import unicodedata
|
||||
|
||||
def auto_int(x):
|
||||
return int(x, 0)
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--apdu", help="Display APDU log", action='store_true')
|
||||
parser.add_argument("--id", help="Identity to initialize", type=auto_int)
|
||||
parser.add_argument("--pin", help="Set a PINs to backup the seed for future use")
|
||||
parser.add_argument("--prefix", help="Derivation prefix")
|
||||
parser.add_argument("--passphrase", help="Derivation passphrase")
|
||||
parser.add_argument("--words", help="Derivation phrase")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if (args.id is None) or args.id > 2:
|
||||
raise Exception("Missing identity number [0-2]")
|
||||
|
||||
dongle = getDongle(args.apdu)
|
||||
|
||||
def enter_if_none_and_normalize(hint, strg):
|
||||
if strg is None: # or len(string) == 0: len 0 is accepted, to specify without being bothered by a message
|
||||
strg = getpass.getpass(hint)
|
||||
if len(strg) != 0 :
|
||||
strg = unicodedata.normalize('NFKD', u''+strg)
|
||||
return strg
|
||||
|
||||
if (args.id < 2):
|
||||
args.pin = enter_if_none_and_normalize("PIN: ", args.pin)
|
||||
if args.pin is None or len(args.pin) == 0:
|
||||
raise Exception("Missing PIN for persistent identity")
|
||||
elif not args.pin is None:
|
||||
raise Exception("Can't set a PIN for the temporary identity")
|
||||
|
||||
args.prefix = enter_if_none_and_normalize("Derivation prefix: ", args.prefix)
|
||||
args.passphrase = enter_if_none_and_normalize("Derivation passphrase: ", args.passphrase)
|
||||
args.words = enter_if_none_and_normalize("Derivation phrase: ", args.words)
|
||||
|
||||
if args.pin:
|
||||
apdudata = bytearray([len(args.pin)]) + bytearray(args.pin, 'utf8')
|
||||
else:
|
||||
apdudata = bytearray([0])
|
||||
|
||||
if args.prefix:
|
||||
apdudata += bytearray([len(args.prefix)]) + bytearray(args.prefix, 'utf8')
|
||||
else:
|
||||
apdudata += bytearray([0])
|
||||
|
||||
if args.passphrase:
|
||||
apdudata += bytearray([len(args.passphrase)]) + bytearray(args.passphrase, 'utf8')
|
||||
else:
|
||||
apdudata += bytearray([0])
|
||||
|
||||
if args.words:
|
||||
apdudata += bytearray([len(args.words)]) + bytearray(args.words, 'utf8')
|
||||
else:
|
||||
apdudata += bytearray([0])
|
||||
|
||||
apdu = bytearray([0xE0, 0xD0, args.id, 0x00, len(apdudata)]) + apdudata
|
||||
dongle.exchange(apdu, timeout=3000)
|
|
@ -0,0 +1,50 @@
|
|||
"""
|
||||
*******************************************************************************
|
||||
* Ledger Blue
|
||||
* (c) 2016 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.
|
||||
********************************************************************************
|
||||
"""
|
||||
|
||||
from .ecWrapper import PrivateKey
|
||||
from .comm import getDongle
|
||||
from .deployed import getDeployedSecretV1, getDeployedSecretV2
|
||||
from .hexLoader import HexLoader
|
||||
import argparse
|
||||
import binascii
|
||||
import sys
|
||||
|
||||
def auto_int(x):
|
||||
return int(x, 0)
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--targetId", help="Set the chip target ID", type=auto_int)
|
||||
parser.add_argument("--rootPrivateKey", help="Set the root private key")
|
||||
parser.add_argument("--apdu", help="Display APDU log", action='store_true')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.targetId == None:
|
||||
args.targetId = 0x31000002
|
||||
if args.rootPrivateKey == None:
|
||||
privateKey = PrivateKey()
|
||||
publicKey = binascii.hexlify(privateKey.pubkey.serialize(compressed=False))
|
||||
print("Generated random root public key : %s" % publicKey)
|
||||
args.rootPrivateKey = privateKey.serialize()
|
||||
|
||||
dongle = getDongle(args.apdu)
|
||||
|
||||
secret = getDeployedSecretV2(dongle, bytearray.fromhex(args.rootPrivateKey), args.targetId)
|
||||
loader = HexLoader(dongle, 0xe0, True, secret)
|
||||
loader.exchange(0xE0, 0, 0, 0, loader.encryptAES(b'\xB0'));
|
|
@ -0,0 +1,57 @@
|
|||
"""
|
||||
*******************************************************************************
|
||||
* Ledger Blue
|
||||
* (c) 2016 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.
|
||||
********************************************************************************
|
||||
"""
|
||||
|
||||
DEFAULT_ALIGNMENT = 1024
|
||||
|
||||
from .ecWrapper import PrivateKey
|
||||
from .comm import getDongle
|
||||
from .hexParser import IntelHexParser, IntelHexPrinter
|
||||
from .hexLoader import HexLoader
|
||||
from .deployed import getDeployedSecretV1, getDeployedSecretV2
|
||||
import argparse
|
||||
import struct
|
||||
import binascii
|
||||
import sys
|
||||
|
||||
def auto_int(x):
|
||||
return int(x, 0)
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--targetId", help="Set the chip target ID", type=auto_int)
|
||||
parser.add_argument("--apdu", help="Display APDU log", action='store_true')
|
||||
parser.add_argument("--rootPrivateKey", help="Set the root private key")
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.targetId is None:
|
||||
args.targetId = 0x31000002
|
||||
if args.rootPrivateKey is None:
|
||||
privateKey = PrivateKey()
|
||||
publicKey = binascii.hexlify(privateKey.pubkey.serialize(compressed=False))
|
||||
print("Generated random root public key : %s" % publicKey)
|
||||
args.rootPrivateKey = privateKey.serialize()
|
||||
|
||||
|
||||
dongle = getDongle(args.apdu)
|
||||
|
||||
secret = getDeployedSecretV2(dongle, bytearray.fromhex(args.rootPrivateKey), args.targetId)
|
||||
loader = HexLoader(dongle, 0xe0, True, secret)
|
||||
|
||||
loader.resetCustomCA()
|
|
@ -0,0 +1,65 @@
|
|||
"""
|
||||
*******************************************************************************
|
||||
* Ledger Blue
|
||||
* (c) 2016 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.
|
||||
********************************************************************************
|
||||
"""
|
||||
|
||||
DEFAULT_ALIGNMENT = 1024
|
||||
|
||||
from .ecWrapper import PrivateKey
|
||||
from .comm import getDongle
|
||||
from .hexParser import IntelHexParser, IntelHexPrinter
|
||||
from .hexLoader import HexLoader
|
||||
from .deployed import getDeployedSecretV1, getDeployedSecretV2
|
||||
import argparse
|
||||
import struct
|
||||
import binascii
|
||||
import sys
|
||||
|
||||
def auto_int(x):
|
||||
return int(x, 0)
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--targetId", help="Set the chip target ID", type=auto_int)
|
||||
parser.add_argument("--apdu", help="Display APDU log", action='store_true')
|
||||
parser.add_argument("--rootPrivateKey", help="Set the root private key")
|
||||
parser.add_argument("--public", help="Custom CA public key to setup (hex encoded)")
|
||||
parser.add_argument("--name", help="Name of the Custom CA (to be displayed on screen upon auth requests)")
|
||||
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.targetId is None:
|
||||
args.targetId = 0x31000002
|
||||
if args.rootPrivateKey is None:
|
||||
privateKey = PrivateKey()
|
||||
publicKey = binascii.hexlify(privateKey.pubkey.serialize(compressed=False))
|
||||
print("Generated random root public key : %s" % publicKey)
|
||||
args.rootPrivateKey = privateKey.serialize()
|
||||
if args.public is None:
|
||||
raise Exception("Missing public key")
|
||||
if args.name is None:
|
||||
raise Exception("Missing certificate name")
|
||||
|
||||
public = bytearray.fromhex(args.public)
|
||||
|
||||
|
||||
dongle = getDongle(args.apdu)
|
||||
|
||||
secret = getDeployedSecretV2(dongle, bytearray.fromhex(args.rootPrivateKey), args.targetId)
|
||||
loader = HexLoader(dongle, 0xe0, True, secret)
|
||||
|
||||
loader.setupCustomCA(args.name, public)
|
|
@ -57,4 +57,4 @@ signature = testMaster.ecdsa_sign(bytes(dataToSign), raw=True)
|
|||
# test signature before printing it
|
||||
if testMaster.pubkey.ecdsa_verify(dataToSign, signature, raw=True):
|
||||
#print("Signer's public: " + binascii.hexlify(testMasterPublic))
|
||||
print(testMaster.ecdsa_serialize(signature).encode('hex'))
|
||||
print(str(testMaster.ecdsa_serialize(signature)).encode('hex'))
|
||||
|
|
Loading…
Reference in New Issue