Skip to content

Commit

Permalink
Custom Errors (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
jshawl authored Feb 13, 2024
1 parent 7995a82 commit 2c7caf7
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 16 deletions.
1 change: 1 addition & 0 deletions lib/minisign.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
require 'minisign/signature'
require 'minisign/private_key'
require 'minisign/key_pair'
require 'minisign/error'
2 changes: 1 addition & 1 deletion lib/minisign/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def self.recreate(options)
begin
# try without a password first
private_key = Minisign::PrivateKey.new(private_key_contents)
rescue RuntimeError
rescue Minisign::PasswordMissingError
print 'Password: '
private_key = Minisign::PrivateKey.new(private_key_contents, prompt)
end
Expand Down
12 changes: 12 additions & 0 deletions lib/minisign/error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module Minisign
class SignatureVerificationError < StandardError
end

class PasswordMissingError < StandardError
end

class PasswordIncorrectError < StandardError
end
end
8 changes: 6 additions & 2 deletions lib/minisign/private_key.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,12 @@ def scrypt_params(bytes)

# @raise [RuntimeError] if the extracted public key does not match the derived public key
def assert_valid_key!
raise 'Missing password for encrypted key' if kdf_algorithm.bytes.sum != 0 && @password.nil?
raise 'Wrong password for that key' if @ed25519_public_key_bytes != ed25519_signing_key.verify_key.to_bytes.bytes
if kdf_algorithm.bytes.sum != 0 && @password.nil?
raise Minisign::PasswordMissingError, 'Missing password for encrypted key'
end
return unless @ed25519_public_key_bytes != ed25519_signing_key.verify_key.to_bytes.bytes

raise Minisign::PasswordIncorrectError, 'Wrong password for that key'
end

def key_data(password, bytes)
Expand Down
25 changes: 18 additions & 7 deletions lib/minisign/public_key.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,8 @@ def key_id
# @raise RuntimeError on mismatching key ids
def verify(signature, message)
assert_matching_key_ids!(signature.key_id, key_id)
ed25519_verify_key.verify(signature.signature, blake2b512(message))
begin
ed25519_verify_key.verify(signature.trusted_comment_signature, signature.signature + signature.trusted_comment)
rescue Ed25519::VerifyError
raise 'Comment signature verification failed'
end
verify_message_signature(signature.signature, message)
verify_comment_signature(signature.trusted_comment_signature, signature.signature + signature.trusted_comment)
"Signature and comment signature verified\nTrusted comment: #{signature.trusted_comment}"
end

Expand All @@ -50,6 +46,18 @@ def to_s

private

def verify_comment_signature(signature, comment)
ed25519_verify_key.verify(signature, comment)
rescue Ed25519::VerifyError
raise Minisign::SignatureVerificationError, 'Comment signature verification failed'
end

def verify_message_signature(signature, message)
ed25519_verify_key.verify(signature, blake2b512(message))
rescue Ed25519::VerifyError => e
raise Minisign::SignatureVerificationError, e
end

def untrusted_comment
if @lines.length == 1
"minisign public key #{key_id}"
Expand All @@ -75,7 +83,10 @@ def key_data
end

def assert_matching_key_ids!(key_id1, key_id2)
raise "Signature key id is #{key_id1}\nbut the key id in the public key is #{key_id2}" unless key_id1 == key_id2
return if key_id1 == key_id2

raise Minisign::SignatureVerificationError,
"Signature key id is #{key_id1}\nbut the key id in the public key is #{key_id2}"
end
end
end
6 changes: 3 additions & 3 deletions spec/minisign/private_key_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
it 'raises if the private key requires a password but is not supplied' do
expect do
Minisign::PrivateKey.new(File.read('test/minisign.key'))
end.to raise_error('Missing password for encrypted key')
end.to raise_error(Minisign::PasswordMissingError, 'Missing password for encrypted key')
end

it 'raises if the password is incorrect for the private key' do
expect do
Minisign::PrivateKey.new(File.read('test/minisign.key'), 'not the right password')
end.to raise_error('Wrong password for that key')
end.to raise_error(Minisign::PasswordIncorrectError, 'Wrong password for that key')
end

it 'parses the cksum_algorithm' do
Expand Down Expand Up @@ -128,7 +128,7 @@
end.not_to raise_error
expect do
Minisign::PrivateKey.new(@private_key.to_s)
end.to raise_error('Missing password for encrypted key')
end.to raise_error(Minisign::PasswordMissingError, 'Missing password for encrypted key')

File.write('test/generated/new-password.key', @private_key)
path = 'test/generated'
Expand Down
12 changes: 9 additions & 3 deletions spec/minisign/public_key_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@
end
it 'raises ed25519 errors for valid signatures but mismatching content' do
@signature = Minisign::Signature.new(File.read('test/example.txt.minisig.unverifiable'))
expect { @pk.verify(@signature, @message) }.to raise_error(Ed25519::VerifyError)
expect do
@pk.verify(@signature, @message)
end.to raise_error(Minisign::SignatureVerificationError, 'signature verification failed!')
end
it 'verifies trusted comments' do
@signature = Minisign::Signature.new(File.read('test/example.txt.minisig.tampered'))
expect { @pk.verify(@signature, @message) }.to raise_error('Comment signature verification failed')
expect do
@pk.verify(@signature,
@message)
end.to raise_error(Minisign::SignatureVerificationError, 'Comment signature verification failed')
end
it 'has a key_id' do
expect(@pk.key_id).to eq('4CB7A94FABA329A6')
Expand All @@ -25,7 +30,8 @@
@signature = Minisign::Signature.new(File.read('test/example.txt.minisig'))
expect do
@pk.verify(@signature, @message)
end.to raise_error("Signature key id is 4CB7A94FABA329A6\nbut the key id in the public key is F15F69C58B18A08")
end.to raise_error(Minisign::SignatureVerificationError,
"Signature key id is 4CB7A94FABA329A6\nbut the key id in the public key is F15F69C58B18A08")
end
it 'can be written to a file' do
expect(@pk.to_s).to eq(File.read('test/minisign.pub'))
Expand Down

0 comments on commit 2c7caf7

Please sign in to comment.