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 )