diff --git a/lib/minisign/private_key.rb b/lib/minisign/private_key.rb index 50fd66f..023b051 100644 --- a/lib/minisign/private_key.rb +++ b/lib/minisign/private_key.rb @@ -18,7 +18,9 @@ class PrivateKey # Minisign::PrivateKey.new('RWRTY0IyEf+yYa5eAX38PgdrI3TMxwy+3sgzpgcZWQXhOKqdf9sAAAACAAAAAAAAAEAAAAAAHe8Olzttgk6k5pZyT3CyCTcTAV0bLN3kq5CUqhLjqSdYZ6oEWs/S7ztaephS+/jwnuOElLBKkg3Sd56jzyvMwL4qStNUTyPDqckNjniw2SlowmHN8n5NnR47gvqjo96E+vakpw8v5PE=', 'password') def initialize(str, password = nil) contents = str.split("\n") - bytes = Base64.decode64(contents.last).bytes + decoded = Base64.decode64(contents.last) + @untrusted_comment = contents.first.split('untrusted comment: ').last + bytes = decoded.bytes @signature_algorithm, @kdf_algorithm, @cksum_algorithm = [bytes[0..1], bytes[2..3], bytes[4..5]].map { |a| a.pack('U*') } raise 'Missing password for encrypted key' if @kdf_algorithm.bytes.sum != 0 && password.nil? @@ -26,13 +28,14 @@ def initialize(str, password = nil) @kdf_salt = bytes[6..37] @kdf_opslimit = bytes[38..45].pack('V*').unpack('N*').sum @kdf_memlimit = bytes[46..53].pack('V*').unpack('N*').sum - key_data_bytes = if password - kdf_output = derive_key(password, @kdf_salt, @kdf_opslimit, @kdf_memlimit) - xor(kdf_output, bytes[54..157]) - else - bytes[54..157] - end - @key_id, @secret_key, @public_key, @checksum = key_data(key_data_bytes) + @keynum_sk = bytes[54..157].pack('C*') + @key_data_bytes = if password + kdf_output = derive_key(password, @kdf_salt, @kdf_opslimit, @kdf_memlimit) + xor(kdf_output, bytes[54..157]) + else + bytes[54..157] + end + @key_id, @secret_key, @public_key, @checksum = key_data(@key_data_bytes) assert_keypair_match! end # rubocop:enable Layout/LineLength @@ -91,5 +94,13 @@ def sign(filename, message, comment = nil) '' ].join("\n") end + + def to_s + kdf_salt = @kdf_salt.pack('C*') + kdf_opslimit = [@kdf_opslimit, 0].pack('L*') + kdf_memlimit = [@kdf_memlimit, 0].pack('L*') + data = "Ed#{kdf_algorithm}B2#{kdf_salt}#{kdf_opslimit}#{kdf_memlimit}#{@keynum_sk}" + "untrusted comment: #{@untrusted_comment}\n#{Base64.strict_encode64(data)}\n" + end end end diff --git a/spec/minisign/private_key_spec.rb b/spec/minisign/private_key_spec.rb index de55977..55a7a6c 100644 --- a/spec/minisign/private_key_spec.rb +++ b/spec/minisign/private_key_spec.rb @@ -71,6 +71,10 @@ computed_checksum = blake2b256(key_data).bytes expect(@private_key.checksum).to eq(computed_checksum) end + + it 'can be written to a file' do + expect(@private_key.to_s).to eq(File.read('test/minisign.key')) + end end describe 'sign' do