public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/1] BTWinLinkKeyExport - Tool to export link-keys stored by the WIDCOMM stack
@ 2009-05-22 13:38 Alexander Holler
  2009-05-22 19:26 ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 3+ messages in thread
From: Alexander Holler @ 2009-05-22 13:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Alexander Holler

I've used this for dualboot-systems because I didn't want to
pair the devices every time I've switched systems.

Currently it exports the keys using the old bluez format with files
named 'link_key' and 'linkkeys'. To use it with newer versions of bluez
it has either to be modified or someone has to write an import.
---
 tools/windows/BTWinLinkKeyExport.cpp |  210 ++++++++++++++++++++++++++++++++++
 1 files changed, 210 insertions(+), 0 deletions(-)
 create mode 100644 tools/windows/BTWinLinkKeyExport.cpp

diff --git a/tools/windows/BTWinLinkKeyExport.cpp b/tools/windows/BTWinLinkKeyExport.cpp
new file mode 100644
index 0000000..deadabe
--- /dev/null
+++ b/tools/windows/BTWinLinkKeyExport.cpp
@@ -0,0 +1,210 @@
+//
+// BTWinLinkKeyExport.cpp
+//
+// Exports bluetooth-link-keys stored by the WIDCOMM stack for use with
+// Dual- or Multi-booting systems.
+//
+// Written 2004 by Alexander Holler.
+//
+// This source is free in every aspect. You can use, modify, distribute
+// or sell it at your wish. You can even replace my name with yours if
+// that would earn you some credits you otherwise wouldn't get.
+//
+// No warrantys are given. This software might destroy your hardware,
+// software or datas.
+//
+// This software uses functions like sscanf() and such bad things,
+// feel free to make it safe up to point your security-officer wants it.
+//
+// To compile it I've used the free Borland Compiler, but it should work using
+// any compiler. For bcc I've used the following few lines:
+//
+// path=%path%;d:\Programme\Borland\Bcc55\bin
+// bcc32 -O2 -DNDEBUG -c BTWinLinkKeyExport.cpp
+// bcc32 -O2 -DNDEBUG BTWinLinkKeyExport.obj
+//
+// (WIDCOMM is a registered trademark of WIDCOMM Inc. and
+// Borland is a trademark of Borland Software Corporation)
+//
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <string>
+
+#include <windows.h>
+#include <wincrypt.h>
+
+typedef unsigned char uint8_t;
+
+#pragma pack(1)
+
+typedef struct {
+  uint8_t b[6];
+} bdaddr_t;
+
+#pragma pack(4)
+
+struct link_key {
+  bdaddr_t sba; // Dongle address
+  bdaddr_t dba; // external Device address
+  uint8_t key[16];
+  uint8_t type;
+  time_t  time;
+};
+
+#pragma pack()
+
+static char* local_device;
+
+static void displayLastError(void)
+{
+  LPVOID lpMsgBuf;
+  DWORD msgid=GetLastError();
+  if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+    FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+    NULL, msgid, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+    (LPTSTR) &lpMsgBuf, 0, NULL ))
+    return;
+  fprintf(stderr, "Error %u: %s\n", msgid, lpMsgBuf);
+  LocalFree( lpMsgBuf );
+}
+
+static int exportKey(const char* regkeyname, HCRYPTPROV& hProv, FILE* file,
+  FILE* file2)
+{
+  // This function tries to read the registry entry linkkey, decrypts it and
+  // writes an entry to the link-key-file for linux
+  std::string s=std::string("SOFTWARE\\Widcomm\\BTConfig\\Devices\\") +
+    regkeyname;
+  HKEY rKey=NULL;
+  long rc=RegOpenKeyEx(HKEY_LOCAL_MACHINE, s.c_str(), 0, KEY_READ, &rKey);
+  if(rc!=ERROR_SUCCESS) {
+    LPVOID lpMsgBuf;
+    if(!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+      NULL, rc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
+      0, NULL ))
+      return 0;
+    fprintf(stderr, "Error %u: %s\n", rc, lpMsgBuf);
+    LocalFree( lpMsgBuf );
+    return 1;
+  }
+  BYTE keybuf[1024]; // I'm lazy, fixed size
+  DWORD keybuflen=sizeof(keybuf);
+  DWORD type;
+  rc=RegQueryValueEx(rKey, "LinkKey", NULL, &type, keybuf, &keybuflen);
+  RegCloseKey(rKey);
+  if(rc!=ERROR_SUCCESS)
+    return 0; // No error, just no link key
+  // If anyone wants to implement boundary checks for keybuf,
+  // he has my permissions. ;)
+  DWORD dwDataLen=*((DWORD*)(keybuf+4));
+  unsigned char *importkey=keybuf+8;
+  HCRYPTKEY hKey = NULL;
+  if(!CryptImportKey(hProv, importkey, dwDataLen, 0, 0, &hKey)) {
+    displayLastError();
+    return 2;
+  }
+  unsigned char* realkey=importkey+dwDataLen+4;
+  DWORD dwDataLen2=*((DWORD*)(realkey-4));
+  BYTE* newkey=(BYTE*)malloc(dwDataLen2);
+  memcpy(newkey, realkey, dwDataLen2);
+  if(!CryptDecrypt(hKey, 0, 1, 0, newkey, &dwDataLen2 )) {
+    displayLastError();
+    CryptDestroyKey(hKey);
+    return 3;
+  }
+  CryptDestroyKey(hKey);
+  struct link_key lkey;
+  memset(&lkey, 0, sizeof(lkey));
+  unsigned adr[6];
+  if(sscanf(regkeyname, "%x:%x:%x:%x:%x:%x", &adr[0], &adr[1], &adr[2],
+    &adr[3],&adr[4], &adr[5])!= 6)
+    return 4;
+  for(int i=0; i<6; i++)
+    lkey.dba.b[5-i]=adr[i];
+  if(sscanf(local_device, "%x:%x:%x:%x:%x:%x", &adr[0], &adr[1], &adr[2],
+    &adr[3],&adr[4], &adr[5])!= 6)
+    return 5;
+  for(int i=0; i<6; i++)
+    lkey.sba.b[5-i]=adr[i];
+  for(int i=0; i<16; i++)
+    lkey.key[i]=newkey[dwDataLen2-1-i];
+  lkey.time=time(NULL); // We are faking as this is not needed for operation
+  lkey.type=0; // I don't know the types, but my devices are all having 0
+  if(fwrite(&lkey, sizeof(lkey), 1, file)!=1)
+    return 6;
+  for(int i=0; i<17; i++)
+    // I haven't checked if bluez treads them case insensitiv, so we are
+    // exporting them like they were originally found in bluez (uppercase)
+    fprintf(file2, "%c", toupper(regkeyname[i]));
+  fprintf(file2, " ");
+  for(int i=0; i<16; i++)
+    fprintf(file2, "%02X", lkey.key[i]);
+  fprintf(file2, " 0%c", 0x0a);
+  printf("Link key for %s exported.\n", regkeyname);
+  return 0;
+}
+
+static void showHelp(void)
+{
+  printf("\nBTLinkKeyExport V1.0\nWritten 2004 Alexander Holler\n"
+      "Free in every aspect. See the source for details.\n\n");
+  printf("  Usage: BTLinkKeyExport localDeviceMAC\n");
+  printf("  Where localDeviceMAC is in the form xx:xx:xx:xx:xx:xx\n");
+}
+
+int main(int argc, char **argv)
+{
+  if(argc!=2) {
+    showHelp();
+    return 1;
+  }
+  if(strlen(argv[1])!=17) {
+    showHelp();
+    return 2;
+  }
+  local_device=argv[1];
+  FILE* file=fopen("link_key", "wb");
+  if(!file) {
+    fprintf(stderr, "Unable to open file 'link_key' for writing!\n");
+    return 3;
+  }
+  FILE* file2=fopen("linkkeys", "wb");
+  if(!file2) {
+    fprintf(stderr, "Unable to open file 'linkkeys' for writing!\n");
+    return 3;
+  }
+  const char* provider="Microsoft Base Cryptographic Provider v1.0";
+  const char* container="Widcomm Bluetooth Key Container Name";
+  HCRYPTPROV hProv = NULL;
+  if(!CryptAcquireContext(&hProv, container, provider, 1 /* dwProviderType */,
+    0x20 /* dwFlags */ )) {
+    displayLastError();
+    fclose(file);
+    return 4;
+  }
+  HKEY rKey;
+  RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Widcomm\\BTConfig\\Devices", 0,
+    KEY_READ, &rKey);
+  int ret=0;
+  for(unsigned i=0; ; i++) {
+    char rkeyname[255];
+    DWORD rkeynamelen=sizeof(rkeyname);
+    FILETIME ftLastWriteTime;
+    int rc=RegEnumKeyEx(rKey, i, rkeyname, &rkeynamelen, NULL, NULL, NULL,
+      &ftLastWriteTime);
+    if(rc!=ERROR_SUCCESS)
+      break;
+    ret=exportKey(rkeyname, hProv, file, file2);
+    if(ret) {
+      ret+=4;
+      break; // An error occured
+    }
+  }
+  RegCloseKey(rKey);
+  CryptReleaseContext(hProv, 0);
+  fclose(file);
+  return ret;
+}
-- 
1.6.0.4


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/1] BTWinLinkKeyExport - Tool to export link-keys stored by the WIDCOMM stack
  2009-05-22 13:38 [PATCH 1/1] BTWinLinkKeyExport - Tool to export link-keys stored by the WIDCOMM stack Alexander Holler
@ 2009-05-22 19:26 ` Luiz Augusto von Dentz
  2009-05-22 20:59   ` Alexander Holler
  0 siblings, 1 reply; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2009-05-22 19:26 UTC (permalink / raw)
  To: Alexander Holler; +Cc: linux-bluetooth

Hi Alexander,

On Fri, May 22, 2009 at 10:38 AM, Alexander Holler <holler@ahsoftware.de> wrote:
> I've used this for dualboot-systems because I didn't want to
> pair the devices every time I've switched systems.
>
> Currently it exports the keys using the old bluez format with files
> named 'link_key' and 'linkkeys'. To use it with newer versions of bluez
> it has either to be modified or someone has to write an import.

Im afraid this is not really useful anymore, at least not if you
expect to things like the new gnome-bluetooth to work since bluetoothd
needs the sdp records the device export in order to probe the driver
which takes care of profiles. In other words profiles won't just work
because you got the linkkey. Despite this I don't think such thing
belongs to BlueZ codebase, nobody will be going to maintain a windows
c++ source code.

-- 
Luiz Augusto von Dentz
Engenheiro de Computação

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/1] BTWinLinkKeyExport - Tool to export link-keys stored by the WIDCOMM stack
  2009-05-22 19:26 ` Luiz Augusto von Dentz
@ 2009-05-22 20:59   ` Alexander Holler
  0 siblings, 0 replies; 3+ messages in thread
From: Alexander Holler @ 2009-05-22 20:59 UTC (permalink / raw)
  To: linux-bluetooth

Hi lUiz,

Luiz Augusto von Dentz schrieb:

> Im afraid this is not really useful anymore, at least not if you
> expect to things like the new gnome-bluetooth to work since bluetoothd
> needs the sdp records the device export in order to probe the driver
> which takes care of profiles. In other words profiles won't just work
> because you got the linkkey. Despite this I don't think such thing
> belongs to BlueZ codebase, nobody will be going to maintain a windows
> c++ source code.

I don't care. I just wanted to post that thing, if someone else is 
interested. I've asked some years ago, and nobody really answered, so it 
rested somewhere in my source-directories, seldom used (just) by me and 
got forgotten. Now it has at least found a place in the mailing-list 
here and I have a clear conscience having it (finally) published.

Kind regards,

Alexander Holler


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-05-22 20:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-22 13:38 [PATCH 1/1] BTWinLinkKeyExport - Tool to export link-keys stored by the WIDCOMM stack Alexander Holler
2009-05-22 19:26 ` Luiz Augusto von Dentz
2009-05-22 20:59   ` Alexander Holler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox