Personal tools

Ace:StorePython

From Adapt

Jump to: navigation, search

The following is some sample code for reading and parsing ACE Token Stores in Python. All samples were tested on RHEL5 against python 2.4.3 with a backport of the hashlib library installed.

Read Token Store

The simpliest way (with no error checking) to read a well-formed token store.

import string
import hashlib

def readHeader(file):
    currLine = file.readline()
    if not currLine:
        return False
    headerParts = string.split(currLine)
    if (len(headerParts) != 6):
        return False
    return headerParts

def readIdentifiers(infile):
    line = infile.readline().rstrip("\n")
    ids = []
    while line != "":
        ids.append(line)        
        line = infile.readline().rstrip("\n")
    return ids

def readProof(infile):
    line = infile.readline().rstrip("\n")
    proof = []
    while line != "":
        proof.append(line)        
        line = infile.readline().rstrip("\n")
    return proof

infile = open("/YOUR_TOKEN_STORE_FILE",'rb')

while 1:
    header = readHeader(infile)
    if not header:
        break
    identifiers = readIdentifiers(infile)
    proof = readProof(infile)

infile.close()

You will end up with three arrays, header which contains the six header components, identifiers containing the identifiers for the entry, and a proof array containing proof levels for the entry.

Calculate a file's proof

The round proof is calculated by digesting the encoded byte arrays in each layer in order, while substituting the previous layer or file's digest where an X appears.

For each layer:

  1. split by :
  2. on each item from the split, convert the hex-encoded to a byte array if not an X
  3. if the split item is an X, substitute the byte array from the previous layer or file's digest
  4. create a digest by concatenating each byte array for that layer (in order left to right)
  5. feed result into next layer
import binascii
...
...
def calculateLevel(lowerHash,rowString):
    hashAlg = hashlib.sha256()    
    for hash in string.split(rowString,":"):
        if (hash == "X"):
            hashAlg.update(lowerHash)
        else:
            hashAlg.update(binascii.a2b_hex(hash))
    return hashAlg.digest()

def calculateProof(file,prooflines):
    digFile = open(file,'rb')
# Note, sha256 hardcoded in this example, store algorithm should be checked
    hashAlg = hashlib.sha256()
    hashAlg.update(digFile.read())
    prevhash = hashAlg.digest()

    for proofLine in proof:
        prevhash = calculateLevel(prevhash,proofLine)
    return binascii.b2a_hex(prevhash)


...
...
myfile = "FILE_TO_CHECK"
...
while 1:
   ...
   proof = readProof(infile)
# using proof lines from above, compute a files's proof
   if myfile in identifiers:
      print calculateProof(myfile,proof)
   

This example will read the FILE_TO_VALIDATE, calculate a digest, then feed that digest into each level of the digest. The final level's digest should be compared to the address of that round stored on the IMS.