kind3r / ttlock-sdk-js

JavaScript port of the TTLock Android SDK
GNU General Public License v3.0
42 stars 20 forks source link

Lock Init #3

Closed Fusseldieb closed 3 years ago

Fusseldieb commented 4 years ago

Which would be the next logical step?

Can I just use await device.device.connect() on the lock or does something else need to be done first?

kind3r commented 4 years ago

Hi, it's not ready yet for use. I built some wrappers around the bluetooth objects (device, service, charcteristics etc.) to ease the communication flow. There is also the command object that builds the command packets. But there is no real communication just yet. Be patient :) Next step for me is to create the logic to read/write the required characteristics (this happens in 20 bytes blocks aparently, that's what the CRLF is for at the end of the last packet, is this something standard ?) and handle subscriptions and notifications (to get responses back from the lock). After that, the initialisation should theoretically be straight forward.

But, even after the init is complete, I still need to find a way to store all the private data about the lock, like passwords, aes key etc. that needs to persist between different runs.

Btw, there is some reading material inside docs/SDK-Analysis.md if you feel like messing up with the lock some more :D

Fusseldieb commented 4 years ago

Hi, it's not ready yet for use.

Yes, I know. I totally don't expect it to work. My question is more asking which is the next step... Since this is the only way of communicating, I had to open an Issue. Would probably be wiser to chat on Disord or Telegram, what do you think?

I built some wrappers around the bluetooth objects (device, service, charcteristics etc.) to ease the communication flow. There is also the command object that builds the command packets. But there is no real communication just yet. Be patient :)

Of course! No problem :)

Next step for me is to create the logic to read/write the required characteristics (this happens in 20 bytes blocks aparently, that's what the CRLF is for at the end of the last packet, is this something standard ?) and handle subscriptions and notifications (to get responses back from the lock).

CRLF as it seems happen on every packet, afaik. If you want I can send you a hci_dump from my cellphone. This is where I got the original info posted in my repo.

After that, the initialisation should theoretically be straight forward.

But, even after the init is complete, I still need to find a way to store all the private data about the lock, like passwords, aes key etc. that needs to persist between different runs.

Yep, I totally get that.

Btw, there is some reading material inside docs/SDK-Analysis.md if you feel like messing up with the lock some more :D

I saw that... Considering what you've done, I think you are already many lightyears ahead of me - Just looking at this confused the heck out of me :D But still, I will look into it as soon as I have some time (and patience), sounds interesting enough.

kind3r commented 4 years ago

CRLF as it seems happen on every packet, afaik. If you want I can send you a hci_dump from my cellphone. This is where I got the original info posted in my repo.

Yeah, I was curious if this is something standard in BLE communication (split read/writes to some characteristic into 20 bytes blocks and then add CRLF to the last one). Probably the 20 bytes is a limit somewhere.

The communication so far seems pretty simple, there is a Command with a structure that you also pointed out in your investigation (header + data + crc) that is being send back and forth via writing and reading some characteristics (via subscriptions or notifications, not sure yet). The data is encrypted using AES, initially before the initialization of the lock there is a default AES key that is being used. The complexity comes from building the data itself. There are a lot of command types and data structure versions for both what the SDK sends to the lock and what the lock replies also.

Fusseldieb commented 4 years ago

Yeah, I was curious if this is something standard in BLE communication (split read/writes to some characteristic into 20 bytes blocks and then add CRLF to the last one). Probably the 20 bytes is a limit somewhere.

From SO:

BLE allows you transfer maximum of 20 bytes.

If you want to send more than 20 bytes, you should define array byte[] to contain how many packets you want.

Source: https://stackoverflow.com/questions/24135682/android-sending-data-20-bytes-by-ble/24178409#24178409

Sending more than 20 bytes via BLE is easily achievable by splitting your data into 20 byte packets and implementing a short delay (i.e. using sleep()) between sending each packet.

Source: https://stackoverflow.com/questions/30130162/how-to-send-more-than-20-bytes-data-over-ble-in-android

before the initialization of the lock there is a default AES key that is being used

I saw that you already have included it into this repo, so I might try it out and see what happens.

There are a lot of command types and data structure versions for both what the SDK sends to the lock and what the lock replies also.

But I think the most important, at least for now, are door locks and newer SDK versions (in my example, it's 05 - yours will probably/hopefully have the same version)

kind3r commented 4 years ago

Ok, so it's a BLE thing. I wonder if it's already implemented in noble or not :D

I saw that you already have included it into this repo, so I might try it out and see what happens.

Already tried it on your packets and it does not work :D

But I think the most important, at least for now, are door locks and newer SDK versions (in my example, it's 05 - yours will probably/hopefully have the same version)

Indeed, I don't plan to implement everything the SDK has, at least not now. But still there are quite a lot of features that we need: init, open, close, set/edit fingerprints, pin codes, rfid cards :D

Btw, this is the lock I got: X5 Waterproof Tuya Biometric Fingerprint Lock. Hope it will fit on my door :D

Fusseldieb commented 4 years ago

Ok, so it's a BLE thing. I wonder if it's already implemented in noble or not :D

Maybe this helps: https://github.com/noble/noble/issues/877 and/or https://github.com/noble/noble/issues/400

Already tried it on your packets and it does not work :D

Yes, but my packets are already on a set up lock and are encrypted with a secret key. I mean trying it on an uninitialized/factory reset lock. I might try it today and send you a hci_dump or something.

Indeed, I don't plan to implement everything the SDK has, at least not now. But still there are quite a lot of features that we need: init, open, close, set/edit fingerprints, pin codes, rfid cards :D

That's true. Hopefully you/we can get this right :)

Btw, this is the lock I got: X5 Waterproof Tuya Biometric Fingerprint Lock. Hope it will fit on my door :D

Seems pretty similar to mine. I hope it works :)

kind3r commented 4 years ago

Maybe this helps: noble/noble#877 and/or noble/noble#400

Good find, thing is I'm using @abandonware/noble which should be an updated version as the original noble is no longer maintained. I see that the MTU is updated when the device is connected. And knowing a thing or two about networking both devices have to agree on a value which would be the the lowest supported out of the two devices. So the lock would be the limiting factor here. Anyway, it does not really matter.

Yes, but my packets are already on a set up lock and are encrypted with a secret key. I mean trying it on an uninitialized/factory reset lock. I might try it today and send you a hci_dump or something.

Indeed, dumping from a reseted lock would be an ideea, but you would have to trigger it to tell you something. We'll get there soon.

Seems pretty similar to mine. I hope it works :)

They are all very similar, probably they run the same hardware inside, just small variations on the design, like the 'waterproofing' on the X5. I'm more woried about the build quality, cause at $100 ... even my current cylinder was more expensive than that.

Fusseldieb commented 4 years ago

Good find, thing is I'm using @abandonware/noble which should be an updated version as the original noble is no longer maintained. I see that the MTU is updated when the device is connected. And knowing a thing or two about networking both devices have to agree on a value which would be the the lowest supported out of the two devices. So the lock would be the limiting factor here. Anyway, it does not really matter.

Oh right, I didn't realize that I was on the wrong repo ahaha Well, should really not matter that much. If the MTU isn't changeable, we could just send multiple packets like the official TTLock App and lock does. Might hit the performance a little bit (same as on the official app), but when it works improvements can be made anytime :)

Indeed, dumping from a reseted lock would be an ideea, but you would have to trigger it to tell you something. We'll get there soon.

Since I use my Android phone to make the hci_dump, I can pair it using the official TTLock app and then get the dump. It should reveal the entire sequence and we should be able to decode them, since we have the AESKey for uninitialized locks.

They are all very similar, probably they run the same hardware inside, just small variations on the design, like the 'waterproofing' on the X5. I'm more woried about the build quality, cause at $100 ... even my current cylinder was more expensive than that.

Yep, same here. But they are holding together better than our locks out of stainless steel that we had previously (purchased locally and were really expensive), which is amazing. Our kitchen door constantly slams close and while previously the stainless steel thing would fall apart (the handles would come loose and fall to the ground every so often), the current TTLocks are holding together incredibly well. Almost sounds like an advertisement, but it's just the truth. I have these locks almost a year now. 4 of them in use and 1 is still packed somewhere.

PS: And by slamming the kitchen door shut, I mean for real. Sometimes you can hear - and even feel - the "BLAM" through the entire house ahahaha Don't know how much longer they will hold together, but until now they're still in perfect shape.

kind3r commented 4 years ago

Since I use my Android phone to make the hci_dump, I can pair it using the official TTLock app and then get the dump. It should reveal the entire sequence and we should be able to decode them, since we have the AESKey for uninitialized locks.

Unless you can sniff the whole sequence I don't think you will be able to get anywhere, cause it's not a pairing between the phone and the lock. If I'm reading the API correctly, first the SDK sends a request for the lock's AES key, and after that everything is back and forth is encrypted using that key. Anyone can connect to the lock, but won't be able to do anything anymore since all communication has to be encrypted with the new key.

Don't know how much longer they will hold together, but until now they're still in perfect shape.

Well, that's good to hear :D I'm planning on using mine on my apartment door. It will be sortof useless now, since I don't go out anymore, but will be good when I get back from my monthly shopping and don't have to look for the keys etc.

Fusseldieb commented 4 years ago

Unless you can sniff the whole sequence I don't think you will be able to get anywhere, cause it's not a pairing between the phone and the lock. If I'm reading the API correctly, first the SDK sends a request for the lock's AES key, and after that everything is back and forth is encrypted using that key. Anyone can connect to the lock, but won't be able to do anything anymore since all communication has to be encrypted with the new key.

I think you're not getting me ahaha I mean: My phone listens to the entire Bluetooth packets going from- and to it. If I reset the lock completely, I can connect to the lock and then disconnect again. Doing that my phone's dump already has the entire packets that it used for pairing. I hope you get me now.

Well, that's good to hear :D I'm planning on using mine on my apartment door. It will be sortof useless now, since I don't go out anymore, but will be good when I get back from my monthly shopping and don't have to look for the keys etc.

Ahh nice! Just as a heads-up: When I would go shopping and then get home, it happened really often that my hand/finger that I use to unlock the door was busy holding things, which then made me put down or even drop groceries in order to unlock the damn door. My tip would be investing in a NFC bracelet or, after you've cracked the ttlock-sdk, implement a face-recognition or something or similar on HA to unlock the door ;)

kind3r commented 4 years ago

My phone listens to the entire Bluetooth packets going from- and to it

Ok, not sniffing but local packet capture :) What do you use for this ? Does it require a rooted phone ?

My tip would be investing in a NFC bracelet

It does come with 2 bracelets, and some (5?) keychain cards. But some people were complaining about some of those missing.

Fusseldieb commented 4 years ago

My phone listens to the entire Bluetooth packets going from- and to it

Ok, not sniffing but local packet capture :)

Yep, it captures local packets coming from- and to the remote device, which is sufficient.

What do you use for this ?

A native Android developer option

Does it require a rooted phone ?

Well, no, but you can get the logs easier if you have root. However, if your phone is not rooted, like mine, you still can, it's just a little bit annoying-er. I did it by enabling HCI logs, doing my BLE stuff, creating a "Full crash log" in the developer options and sending the zip file to myself. Inside the zip, there is a file called hci_dump or something similar; You can open it using Wireshark and it'll show you everything that happened on Bluetooth since the phone last booted or something :) On older Android versions (below 4 or 5 I think) the hci_dump would be placed inside internal storage as soon as you enabled that option. Some phones even still do this, I think. But more and more are trying to "hide" it like mentioned above.

It does come with 2 bracelets, and some (5?) keychain cards. But some people were complaining about some of those missing.

Afaik, mine didn't come with bracelets, but with some keychain cards. If it doesn't, you can probably just use normal NFC Mifare bracelets. They're pretty pretty cheap.

kind3r commented 4 years ago

A native Android developer option

Gotcha, thanks for the tip. I'll look for that option in case my sniffer will not work.

Afaik, mine didn't come with bracelets, but with some keychain cards. If it doesn't, you can probably just use normal NFC Mifare bracelets. They're pretty pretty cheap.

You can always make a bracelet from the keychain cards. 3D printing to the rescue :D

I'm struggling now with reading characteristics. I am able to connect to devices around me and get the full service and characteristics list, but I can't read any data from the characteristics. Perhaps the characteristics I'm trying to read don't work like that. Maybe you can try it and see if it can read anything from the locks.

Fusseldieb commented 4 years ago

A native Android developer option

Gotcha, thanks for the tip. I'll look for that option in case my sniffer will not work.

Afaik, mine didn't come with bracelets, but with some keychain cards. If it doesn't, you can probably just use normal NFC Mifare bracelets. They're pretty pretty cheap.

You can always make a bracelet from the keychain cards. 3D printing to the rescue :D

Ahahaha, yes, you could do that too.

I'm struggling now with reading characteristics. I am able to connect to devices around me and get the full service and characteristics list, but I can't read any data from the characteristics. Perhaps the characteristics I'm trying to read don't work like that. Maybe you can try it and see if it can read anything from the locks.

Would love to. Having the lock at hand it's certainly easier.

Can I contact you over any platform that has real-time chat (Like Telegram or Discord)?

kind3r commented 4 years ago

Can I contact you over any platform that has real-time chat (Like Telegram or Discord)?

Going to bed now :) But I'll be looking for my discord account, have not used it in a long time :P Btw, what timezone are you on ? I'm GMT+2.

Fusseldieb commented 4 years ago

Can I contact you over any platform that has real-time chat (Like Telegram or Discord)?

Going to bed now :) But I'll be looking for my discord account, have not used it in a long time :P Btw, what timezone are you on ? I'm GMT+2.

Oh, no problem! Tomorrow then.

I'm GMT-3 (Brasilia).

Have a good night!

kind3r commented 4 years ago

Ok, so good news, bad news :/

Good news I got my lock and found my discord user: kind3r#3364

Bad news, the lock is WiFi :(

Fusseldieb commented 4 years ago

Good news I got my lock and found my discord user: kind3r#3364

I sent you an invite over there

Bad news, the lock is WiFi :(

That's quite a surprise... Does it just have Wifi?

kind3r commented 3 years ago

Ok, so the demo scan now correctly reads all readable characteristics. The problem was that once a device is disconnected, noble forgets about all the discovered characteristics so if you want to read/write anything you have to do the service and characteristics discovery + your read/write operation(s) inside one connection.

Fusseldieb commented 3 years ago

Ok, so the demo scan now correctly reads all readable characteristics. The problem was that once a device is disconnected, noble forgets about all the discovered characteristics so if you want to read/write anything you have to do the service and characteristics discovery + your read/write operation(s) inside one connection.

Can't we cache the characteristics for a certain lock? Like a store/object or something...?

kind3r commented 3 years ago

Can't we cache the characteristics for a certain lock? Like a store/object or something...?

Yeah, we will, now that I know how it works I will implement all this in the TTDevice and NobleDevice.

kind3r commented 3 years ago

I'll close this issue and leave it for posterity :)