def main(): # setup the path for working directories SSD_TOOLS_DIR = os.getcwd() keystore_fn = os.path.join("keys", "keystore.dat") keystore = key_config_parser.get_ssd_keystore("key_config.xml") # open output file if os.path.exists(keystore_fn): os.chmod(keystore_fn, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO | stat.S_IWRITE) os.remove(keystore_fn) keystore_fp = open(keystore_fn, "wb") zero_buf = '' # TODO: remove zeros.dat # open and read the zero buf file with open("zeros.dat", "rb") as zb_fo: zero_buf = zb_fo.read() if len(keystore) > 10: print("Error: Too many keys in keyfile (" + len(keystore) + ")") dirbuf = io.BytesIO() keybuf = io.BytesIO() # write zeros for the magic number (version) dirbuf.write(zero_buf[0:4]) # write the number of keys (4 bytes) dirbuf.write(binascii.unhexlify(_to_hex_string(len(keystore)))) # the directory contains an entry for the directory itself. dir_key_start = '' # 10 keys is the max size for the directory. # Zero out all entries for ii in range(10): # key metadata size dirbuf.write(zero_buf[0:4]) # key_id is sha 256 dirbuf.write(zero_buf[0:32]) # save the offset in the directory where the key info should # start if (ii == 0): dir_key_start = dirbuf.tell() # Save this for later. Arguably better than seeking to the end, # then calling tell again? dirbuf_len = dirbuf.tell() dirbuf.seek(dir_key_start) for key in keystore: # open file keyid_fn = os.path.normpath(key[1]) print("Reading key_id file: " + os.path.abspath(keyid_fn)) keyid_fp = open(keyid_fn, "rb") # read file keyid_buf = keyid_fp.read() keyid_fp.close() # write key metadata (4 bytes) dirbuf.write(key[2]) # key id must be less than 32 bytes if len(keyid_buf) > 32: print("Key ID not the correct length: " + os.path.normpath(keyid_fn)) # TODO: return an error # write key id to keystore directory dirbuf.write(keyid_buf) # pad the keyid if necessary if len(keyid_buf) < 32: dirbuf.write(zero_buf[0:32 - len(keyid_buf)]) ########### # Encrypted Message Version: HMAC-256 AES-128 keybuf.write("\x01\x00\x00\x00") # add space for auth_tag keybuf.write(zero_buf[0:32]) key_fn = os.path.normpath(key[0]) # write the key size (4 bytes) keybuf.write( binascii.unhexlify(_to_hex_string(os.path.getsize(key_fn)))) # add space for IV keybuf.write(zero_buf[0:16]) # open file print("Reading key file: " + os.path.abspath(key_fn)) key_file_fp = open(key_fn, "rb") # read file key_file_buf = key_file_fp.read() key_file_fp.close() # write plaintext key file to output file keybuf.write(key_file_buf) direntrybuf = io.BytesIO() # Encrypted Message Version: HMAC-256 AES-128 direntrybuf.write("\x01\x00\x00\x00") # add space for auth_tag direntrybuf.write(zero_buf[0:32]) # write the key size (4 bytes) direntrybuf.write(binascii.unhexlify(_to_hex_string(dirbuf_len))) # add space for IV direntrybuf.write(zero_buf[0:16]) # Write directory direntrybuf.write(dirbuf.getvalue()) headerbuf = io.BytesIO() headerbuf.write("ssdksimg") # Write header, directory entry and key entries to output file keystore_fp.write(headerbuf.getvalue()) keystore_fp.write(direntrybuf.getvalue()) keystore_fp.write(keybuf.getvalue()) # close file keystore_fp.close()
def main(): # setup the path for working directories SSD_TOOLS_DIR = os.getcwd() keystore_fn = os.path.join("keys", "keystore.dat") keystore = key_config_parser.get_ssd_keystore("key_config.xml") # open output file if os.path.exists(keystore_fn): os.chmod(keystore_fn, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO | stat.S_IWRITE) os.remove(keystore_fn) keystore_fp = open(keystore_fn, "wb") zero_buf = '' # TODO: remove zeros.dat # open and read the zero buf file with open("zeros.dat", "rb") as zb_fo: zero_buf = zb_fo.read() if len(keystore) > 10: print("Error: Too many keys in keyfile (" + len(keystore) + ")") dirbuf = io.BytesIO() keybuf = io.BytesIO() # write zeros for the magic number (version) dirbuf.write(zero_buf[0:4]) # write the number of keys (4 bytes) dirbuf.write(binascii.unhexlify(_to_hex_string(len(keystore)))) # the directory contains an entry for the directory itself. dir_key_start = '' # 10 keys is the max size for the directory. # Zero out all entries for ii in range(10): # key metadata size dirbuf.write(zero_buf[0:4]) # key_id is sha 256 dirbuf.write(zero_buf[0:32]) # save the offset in the directory where the key info should # start if (ii == 0): dir_key_start = dirbuf.tell() # Save this for later. Arguably better than seeking to the end, # then calling tell again? dirbuf_len = dirbuf.tell() dirbuf.seek(dir_key_start) for key in keystore: # open file keyid_fn = os.path.normpath(key[1]) print("Reading key_id file: " + os.path.abspath(keyid_fn)) keyid_fp = open(keyid_fn, "rb") # read file keyid_buf = keyid_fp.read() keyid_fp.close() # write key metadata (4 bytes) dirbuf.write(key[2]) # key id must be less than 32 bytes if len(keyid_buf) > 32: print("Key ID not the correct length: " + os.path.normpath(keyid_fn)) # TODO: return an error # write key id to keystore directory dirbuf.write(keyid_buf) # pad the keyid if necessary if len(keyid_buf) < 32: dirbuf.write(zero_buf[0:32 - len(keyid_buf)]) ########### # Encrypted Message Version: HMAC-256 AES-128 keybuf.write("\x01\x00\x00\x00") # add space for auth_tag keybuf.write(zero_buf[0:32]) key_fn = os.path.normpath(key[0]) # write the key size (4 bytes) keybuf.write(binascii.unhexlify( _to_hex_string(os.path.getsize(key_fn)))) # add space for IV keybuf.write(zero_buf[0:16]) # open file print("Reading key file: " + os.path.abspath(key_fn)) key_file_fp = open(key_fn, "rb") # read file key_file_buf = key_file_fp.read() key_file_fp.close() # write plaintext key file to output file keybuf.write(key_file_buf) direntrybuf = io.BytesIO() # Encrypted Message Version: HMAC-256 AES-128 direntrybuf.write("\x01\x00\x00\x00") # add space for auth_tag direntrybuf.write(zero_buf[0:32]) # write the key size (4 bytes) direntrybuf.write(binascii.unhexlify(_to_hex_string(dirbuf_len))) # add space for IV direntrybuf.write(zero_buf[0:16]) # Write directory direntrybuf.write(dirbuf.getvalue()) headerbuf = io.BytesIO() headerbuf.write("ssdksimg") # Write header, directory entry and key entries to output file keystore_fp.write(headerbuf.getvalue()) keystore_fp.write(direntrybuf.getvalue()) keystore_fp.write(keybuf.getvalue()) # close file keystore_fp.close()