Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Authenticator
=============

Forked off 'authenticator' by IEF, which was forked off 'twostep' by pokey9000, this is Authenticator for Pebble, with patches from rigel314
Forked off 'authenticator' by IEF, which was forked off 'twostep' by pokey9000, this is Authenticator for Pebble, with patches from rigel314 and cwoac

generating multiple Time-based One-Time Passwords, much like Google Authenticator.

Expand All @@ -17,7 +17,7 @@ On most sites, when setting up choose 'show key' when presented with the QR code
3. add it to the end of configuration.txt, following the example in the format
label:secret

4. repeat this for all your keys (don't forget to remove the example)
4. repeat this for all your keys (don't forget to remove the examples)

5. Generate the config by running ./configuration.py

Expand All @@ -27,3 +27,14 @@ label:secret

The above is assuming you have the Pebble SDK installed and configured to compile watch apps.
If not, review: http://developer.getpebble.com/1/01_GetStarted/01_Step_2

Battle.net
----------

Battle.net / guild wars keys are slightly different to handle as they use a variant of the algorithm.
To mark a code as being a battle.net key, prefix it's label with an underscore ('_' - see the example configuration.txt)

To determine your key, you will need the secret code. You can use [python-bna](https://github.com/Adys/python-bna) to do so.
Once you have your key installed in bna (either by generating a fresh one or using recover) you can get the value from ~/.config/bna/bna.conf

Note that Blizzard seem to be stricter on the timing than google (I suspect that google actually allow you to use +/- a password) - so if you have issues, check your watch's time is correct.
57 changes: 50 additions & 7 deletions configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,29 @@

import base64
import sys
from binascii import unhexlify


secrets = []
labels = []
lengths = []
code_lengths=[]
max_code_length = 6

time_zone = "+0"

def genKeyLine( code ):
def decode( code ):
key_b32 = code.replace(' ','').upper()
key_b32 = key_b32+'='*(32%len(key_b32))
key = base64.b32decode(key_b32)
key_bytes = map(ord,key)
key = base64.b32decode(key_b32)
return map(ord,key)

def battle_decode ( code ):
code = unhexlify( code )
key = map(ord,code)
return key

def genKeyLine( key_bytes ):
lengths.append( len(key_bytes) )
key_hex = ["0x%02X" % x for x in key_bytes]
return "{ " + ', '.join(key_hex) + " },"
Expand All @@ -27,28 +39,59 @@ def genKeyLine( code ):
line = line.strip()
if( line.startswith('#') or not ':' in line ): continue
key,value = line.split(':')

type = "google"
if( line.startswith('_') ):
type = "battle"
key = key[1:]

if( key.lower() == "tz" ):
time_zone = value
else:
labels.append( key )
secrets.append( genKeyLine(value) )
if( type == "battle" ):
code_lengths.append( "8" )
max_code_length = 8
secrets.append( genKeyLine(battle_decode(value)) )
else:
secrets.append( genKeyLine(decode(value)) )
code_lengths.append( "6" )
f.close()

f = open( "src/configuration.h","w" )
f.write( "#ifndef _CONFIGURATION_H_\n#define _CONFIGURATION_H_\n" )
f.write( "#define NUM_SECRETS %i\n" % len(labels) )
f.write( "#define DEFAULT_TIME_ZONE %s\n" % time_zone )
f.write( "char otplabels[NUM_SECRETS][10] = {\n " )
f.write( "#define TOKEN_TEXT \"" )
for _ in range( max_code_length ):
f.write( "X" )
f.write( "\"\n")
f.write( "#define DIGITS_TRUNCATE 1" )
for _ in range( max_code_length ):
f.write( "0" )
f.write( "\n" )

#TODO:: calculate length properly
f.write( "char otplabels[NUM_SECRETS][%s] = {\n " % 20)
for label in labels:
f.write( "\"%s\"," % label )
f.write( "\n};\n" )
f.write( "unsigned char otpkeys[NUM_SECRETS][16] = {\n " )

f.write( "unsigned char otpkeys[NUM_SECRETS][41] = {\n " )
for secret in secrets:
f.write( "%s\n" % secret )
f.write( "};\n" )

f.write ("int otpsizes[NUM_SECRETS] = { ")
for length in lengths:
f.write( "%s," % length )
f.write( "};\n#endif\n" )
f.write( "};\n")

f.write( "int otplengths[NUM_SECRETS] = { ")
for length in code_lengths:
f.write( "%s," % length )
f.write( "};\n")

f.write("#endif\n" )

f.close()
4 changes: 4 additions & 0 deletions configuration.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@
tz:+1
# define your secrets, one per line, in the form
# name:secret
# for battle.net the name must be battle
# and the key is in the form of a 40 character hex string.
fake:pskfb2vhfiegni2h
_bnet:0123456789012345678901234567890123456789

Loading