ruby-gpgme/test/crypto_test.rb

243 строки
7.5 KiB
Ruby

# -*- encoding: utf-8 -*-
require 'test_helper'
require 'tempfile'
describe GPGME::Crypto do
describe "default options functionality" do
it "allows operation from instances normally" do
crypto = GPGME::Crypto.new
encrypted = crypto.encrypt TEXT[:plain], :always_trust => true, :recipients => KEYS.first[:sha]
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
end
it "can set default options when using the instance way" do
crypto = GPGME::Crypto.new :always_trust => true
encrypted = crypto.encrypt TEXT[:plain], :recipients => KEYS.first[:sha]
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
end
it "but they can still be overwritten" do
crypto = GPGME::Crypto.new :always_trust => false
encrypted = crypto.encrypt TEXT[:plain], :always_trust => true, :recipients => KEYS.first[:sha]
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
end
end
describe "roundtrip encryption/decryption" do
it "does the roundtrip encrypting" do
crypto = GPGME::Crypto.new
encrypted = crypto.encrypt TEXT[:plain], :always_trust => true, :recipients => KEYS.first[:sha]
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
end
it "does so even with armored encrypted stuff" do
crypto = GPGME::Crypto.new
encrypted = crypto.encrypt TEXT[:plain], :always_trust => true, :armor => true
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
end
end
describe :encrypt do
it "should raise an error if the recipients aren't trusted" do
assert_raises GPGME::Error::General do
GPGME::Crypto.new.encrypt TEXT[:plain]
end
end
it "doesn't raise an error and returns something when encrypting nothing" do
data = GPGME::Crypto.new.encrypt nil, :always_trust => true
refute_empty data.read
data = GPGME::Crypto.new.encrypt "", :always_trust => true
refute_empty data.read
end
it "can specify which key(s) to use for encrypting with a string" do
crypto = GPGME::Crypto.new :always_trust => true
key = KEYS.last
encrypted = crypto.encrypt TEXT[:plain], :recipients => key[:sha]
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
remove_key key
encrypted.seek 0
assert_raises GPGME::Error::DecryptFailed do
crypto.decrypt(encrypted)
end
import_key key
end
it "can specify which key to use for encrypting with a Key object" do
crypto = GPGME::Crypto.new :always_trust => true
key = KEYS.last
real_key = GPGME::Key.find(:public, key[:sha]).first
encrypted = crypto.encrypt TEXT[:plain], :recipients => real_key
assert_equal TEXT[:plain], crypto.decrypt(encrypted).read
remove_key key
encrypted.seek 0
assert_raises GPGME::Error::DecryptFailed do
crypto.decrypt(encrypted)
end
import_key key
end
it "can also sign at the same time" do
crypto = GPGME::Crypto.new :always_trust => true
encrypted = crypto.encrypt TEXT[:plain], :sign => true
signatures = 0
crypto.verify(encrypted) do |signature|
assert_instance_of GPGME::Signature, signature
signatures += 1
end
assert_equal 1, signatures
end
it "can be signed by more than one person" do
crypto = GPGME::Crypto.new :always_trust => true
encrypted = crypto.encrypt TEXT[:plain], :sign => true, :signers => KEYS.map{|k| k[:sha]}
signatures = 0
crypto.verify(encrypted) do |signature|
assert_instance_of GPGME::Signature, signature
signatures += 1
end
assert_equal 4, signatures
end
it "outputs to a file if specified" do
crypto = GPGME::Crypto.new :always_trust => true
file = Tempfile.new "test"
crypto.encrypt TEXT[:plain], :output => file
file_contents = file.read
file.seek 0
refute_empty file_contents
assert_equal TEXT[:plain], crypto.decrypt(file).read
end
# TODO find how to test
# it "raises GPGME::Error::UnusablePublicKey"
# it "raises GPGME::Error::UnusableSecretKey"
end
describe "symmetric encryption/decryption" do
it "requires a password to encrypt" do
assert_raises GPGME::Error::BadPassphrase do
GPGME::Crypto.new.encrypt TEXT[:plain], :symmetric => true
end
end
it "requires a password to decrypt" do
crypto = GPGME::Crypto.new
encrypted_data = crypto.encrypt TEXT[:plain],
:symmetric => true, :password => "gpgme"
assert_raises GPGME::Error::BadPassphrase do
crypto.decrypt encrypted_data
end
end
it "can encrypt and decrypt with the same password" do
crypto = GPGME::Crypto.new :symmetric => true, :password => "gpgme"
encrypted_data = crypto.encrypt TEXT[:plain]
plain = crypto.decrypt encrypted_data
assert_equal "Hi there", plain.read
end
it "but breaks with different ones" do
crypto = GPGME::Crypto.new
encrypted_data = crypto.encrypt TEXT[:plain],
:symmetric => true, :password => "gpgme"
assert_raises GPGME::Error::DecryptFailed do
crypto.decrypt encrypted_data, :password => "wrong one"
end
end
end
describe :decrypt do
it "decrypts encrypted stuff" do
assert_equal TEXT[:plain], GPGME::Crypto.new.decrypt(TEXT[:encrypted]).read
end
it "will not get into the signatures block if there's none" do
GPGME::Crypto.new.decrypt(TEXT[:encrypted]) do |signature|
flunk "If I'm here means there was some signature"
end
pass
end
it "will get signature elements if the encrypted thing was signed" do
signatures = 0
GPGME::Crypto.new.decrypt(TEXT[:signed]) do |signature|
assert_instance_of GPGME::Signature, signature
signatures += 1
end
assert_equal 1, signatures
end
it "writes to the output if passed" do
buffer = GPGME::Data.new
GPGME::Crypto.new.decrypt(TEXT[:encrypted], :output => buffer)
assert_equal TEXT[:plain], buffer.read
end
# TODO find ways to test this
# it "raises UnsupportedAlgorithm"
# it "raises WrongKeyUsage"
it "raises DecryptFailed when the decrypting key isn't available" do
assert_raises GPGME::Error::DecryptFailed do
GPGME::Crypto.new.decrypt(TEXT[:unavailable])
end
end
end
describe :sign do
it "signs normal strings" do
crypto = GPGME::Crypto.new
signatures = 0
sign = crypto.sign "Hi there"
crypto.verify(sign) do |signature|
assert_instance_of GPGME::Signature, signature
assert signature.valid?
signatures += 1
end
assert_equal 1, signatures
end
# TODO Find how to import an expired public key
# it "raises an error if trying to sign with an expired key" do
# with_key EXPIRED_KEY do
# crypto = GPGME::Crypto.new
# assert_raises GPGME::Error::General do
# sign = crypto.sign "Hi there", :signer => EXPIRED_KEY[:sha]
# end
# end
# end
it "selects who to sign for" do
crypto = GPGME::Crypto.new
sign = crypto.sign "Hi there", :signer => KEYS.last[:sha]
key = GPGME::Key.get(KEYS.last[:sha])
signatures = 0
crypto.verify(sign) do |signature|
assert_instance_of GPGME::Signature, signature
assert_equal key, signature.key
signatures += 1
end
assert_equal 1, signatures
end
end
end