pdb

Simple password manager
Log | Files | Refs | README

update-1-openssl-to-libsodium.lua (2257B)


      1 local crypto = require( "crypto" )
      2 local symmetric = require( "symmetric" )
      3 local json = require( "cjson" )
      4 
      5 local Cipher = "aes-256-ctr"
      6 local Hash = "sha256"
      7 local HMAC = "sha256"
      8 
      9 local KeyLength = 32
     10 local IVLength = 16
     11 local HMACLength = 32
     12 
     13 local SplitCipherTextPattern = "^(" .. string.rep( ".", IVLength ) .. ")(.+)(" .. string.rep( ".", HMACLength ) .. ")$"
     14 
     15 local dir = os.getenv( "HOME" ) .. "/.pdb/"
     16 local paths = {
     17 	old_db = dir .. "db",
     18 	old_key = dir .. "key",
     19 	new_db = dir .. "db2",
     20 	new_key = dir .. "key2",
     21 }
     22 
     23 function io.readable( path )
     24 	local file = io.open( path, "r" )
     25 
     26 	if file then
     27 		file:close()
     28 		return true
     29 	end
     30 
     31 	return false
     32 end
     33 
     34 local function load_old_key()
     35 	local file = assert( io.open( paths.old_key, "r" ) )
     36 
     37 	local key = file:read( "*all" )
     38 	assert( key:len() == KeyLength, "bad key file" )
     39 
     40 	assert( file:close() )
     41 
     42 	return key
     43 end
     44 
     45 local function load_old_db( key )
     46 	local file = assert( io.open( paths.old_db, "r" ) )
     47 
     48 	local contents = assert( file:read( "*all" ) )
     49 	assert( file:close() )
     50 
     51 	local iv, c, hmac = contents:match( SplitCipherTextPattern ) 
     52 	assert( iv, "Corrupt DB" )
     53 
     54 	local key2 = crypto.digest( Hash, key )
     55 	assert( hmac == crypto.hmac.digest( HMAC, c, key2, true ), "Corrupt DB" )
     56 
     57 	local m = crypto.decrypt( Cipher, c, key, iv )
     58 
     59 	return assert( json.decode( m ) )
     60 end
     61 
     62 local function write_new_key()
     63 	local key = symmetric.key()
     64 
     65 	local file, err = io.open( paths.new_key, "w" )
     66 	if not file then
     67 		io.stderr:write( "Unable to open key file for writing: " .. err .. "\n" )
     68 		return os.exit( 1 )
     69 	end
     70 
     71 	assert( file:write( key ) )
     72 	assert( file:close() )
     73 
     74 	return key
     75 end
     76 
     77 local function write_db( db, key )
     78 	local plaintext = assert( json.encode( db ) )
     79 	local ciphertext = symmetric.encrypt( plaintext, key )
     80 
     81 	local file, err = io.open( paths.new_db, "w" )
     82 	if not file then
     83 		io.stderr:write( "Could not open DB for writing: " .. err .. "\n" )
     84 		return os.exit( 1 )
     85 	end
     86 
     87 	file:write( ciphertext )
     88 	local ok = assert( file:close() )
     89 end
     90 
     91 if io.readable( paths.new_key ) or io.readable( paths.new_db ) then
     92 	io.stderr:write( "You already have a key/DB in the new format!\n" )
     93 	return os.exit( 1 )
     94 end
     95 
     96 local db = load_old_db( load_old_key() )
     97 
     98 local key = write_new_key()
     99 write_db( db, key )