1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
|
# -*- encoding: utf-8 -*-
require 'test_helper'
require 'tempfile'
describe GPGME::Crypto do
before do
skip unless ensure_keys GPGME::PROTOCOL_OpenPGP
end
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::UnusablePublicKey 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::NoSecretKey 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::NoSecretKey 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
before do
info = GPGME::Engine.info.first
skip if /\A2\.[01]|\A1\./ === info.version
end
it "requires a password to encrypt" do
GPGME::Crypto.new.encrypt TEXT[:plain], :symmetric => true
end
it "requires a password to decrypt" do
crypto = GPGME::Crypto.new
encrypted_data = crypto.encrypt TEXT[:plain],
:symmetric => true, :password => "gpgme"
crypto.decrypt encrypted_data
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
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::NoSecretKey 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
|