gpgme 1.0.8 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/examples/genkey.rb +1 -1
  2. data/examples/keylist.rb +2 -1
  3. data/examples/roundtrip.rb +7 -4
  4. data/examples/sign.rb +5 -3
  5. data/examples/verify.rb +4 -2
  6. data/ext/gpgme/extconf.rb +58 -0
  7. data/ext/gpgme/gpgme-1.3.1.tar.bz2 +0 -0
  8. data/{gpgme_n.c → ext/gpgme/gpgme_n.c} +8 -8
  9. data/ext/gpgme/libassuan-2.0.2.tar.bz2 +0 -0
  10. data/ext/gpgme/libgpg-error-1.10.tar.bz2 +0 -0
  11. data/lib/gpgme.rb +88 -1541
  12. data/lib/gpgme/compat.rb +2 -0
  13. data/lib/gpgme/constants.rb +23 -0
  14. data/lib/gpgme/crypto.rb +357 -0
  15. data/lib/gpgme/ctx.rb +462 -0
  16. data/lib/gpgme/data.rb +177 -0
  17. data/lib/gpgme/engine.rb +76 -0
  18. data/lib/gpgme/error.rb +66 -0
  19. data/lib/gpgme/io_callbacks.rb +21 -0
  20. data/lib/gpgme/key.rb +242 -0
  21. data/lib/gpgme/key_common.rb +43 -0
  22. data/lib/gpgme/key_sig.rb +35 -0
  23. data/lib/gpgme/misc.rb +66 -0
  24. data/lib/gpgme/signature.rb +85 -0
  25. data/lib/gpgme/sub_key.rb +58 -0
  26. data/lib/gpgme/user_id.rb +20 -0
  27. data/lib/gpgme/version.rb +3 -0
  28. data/test/crypto_test.rb +242 -0
  29. data/test/ctx_test.rb +426 -0
  30. data/test/data_test.rb +116 -0
  31. data/test/files/testkey_pub.gpg +52 -0
  32. data/test/files/testkey_sec.gpg +54 -0
  33. data/test/gpgme_test.rb +12 -0
  34. data/test/key_test.rb +201 -0
  35. data/test/signature_test.rb +48 -0
  36. data/test/sub_key_test.rb +45 -0
  37. data/test/support/resources.rb +516 -0
  38. data/test/test_helper.rb +83 -0
  39. metadata +144 -65
  40. data.tar.gz.sig +0 -3
  41. data/COPYING +0 -340
  42. data/COPYING.LESSER +0 -510
  43. data/Makefile +0 -172
  44. data/Manifest.txt +0 -18
  45. data/README +0 -86
  46. data/Rakefile +0 -17
  47. data/THANKS +0 -15
  48. data/extconf.rb +0 -26
  49. metadata.gz.sig +0 -0
@@ -29,7 +29,7 @@ unless ENV['GNUPGHOME']
29
29
  $stderr.flush
30
30
  exit(1) unless gets.chomp == 'y'
31
31
  end
32
-
32
+
33
33
  def progfunc(hook, what, type, current, total)
34
34
  $stderr.write("#{what}: #{current}/#{total}\r")
35
35
  $stderr.flush
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'gpgme'
3
3
 
4
- GPGME.list_keys(ARGV.shift) do |key|
4
+ ctx = GPGME::Ctx.new
5
+ ctx.each_key(ARGV.shift) do |key|
5
6
  puts(key)
6
7
  end
@@ -28,12 +28,15 @@ plain = 'test test test'
28
28
  puts("Plaintext:\n#{plain}")
29
29
 
30
30
  # Perform symmetric encryption on PLAIN.
31
- cipher = GPGME::encrypt(nil, plain, {:armor => true,
31
+ crypto = GPGME::Crypto.new(:armor => true)
32
+ cipher = crypto.encrypt(plain, {:symmetric => true,
32
33
  # :passphrase_callback => method(:passfunc)
33
34
  })
34
- puts("Ciphertext:\n#{cipher}")
35
+ str = cipher.read
36
+ puts("Ciphertext:\n#{str}")
35
37
 
36
- plain = GPGME::decrypt(cipher, {
38
+ cipher = GPGME::Data.new(str)
39
+ plain = crypto.decrypt(cipher, {
37
40
  # :passphrase_callback => method(:passfunc)
38
41
  })
39
- puts("Plaintext:\n#{plain}")
42
+ puts("Plaintext:\n#{plain.read}")
@@ -24,6 +24,8 @@ unless ENV['GPG_AGENT_INFO']
24
24
  exit(1)
25
25
  end
26
26
 
27
- puts GPGME::clearsign('test test test', {
28
- # :passphrase_callback => method(:passfunc)
29
- })
27
+ crypto = GPGME::Crypto.new
28
+ signature = crypto.clearsign('test test test', {
29
+ # :passphrase_callback => method(:passfunc)
30
+ })
31
+ puts signature.read
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'gpgme'
3
3
 
4
- GPGME::verify(ARGF.read, nil, $stdout) do |signature|
5
- puts(signature.to_s)
4
+ crypto = GPGME::Crypto.new
5
+ signature = GPGME::Data.new(ARGF.read)
6
+ crypto.verify(signature) do |sig|
7
+ puts(sig.to_s)
6
8
  end
@@ -0,0 +1,58 @@
1
+ require 'mkmf'
2
+
3
+ BUILD = Dir::pwd
4
+ SRC = File.expand_path(File.dirname(__FILE__))
5
+ PREFIX = "#{BUILD}/dst/"
6
+
7
+ def sys(*cmd)
8
+ puts " -- #{cmd.join(' ')}"
9
+
10
+ unless ret = xsystem(cmd.join(' '))
11
+ raise "#{cmd.join(' ')} failed!"
12
+ end
13
+
14
+ ret
15
+ end
16
+
17
+ def build(tgz, *flags)
18
+ sys("tar xjvf #{tgz}")
19
+
20
+ Dir.chdir(File.basename(tgz, '.tar.bz2')) do
21
+ sys("./configure --prefix=#{PREFIX} --disable-shared --enable-static --with-pic", *flags)
22
+ sys("make")
23
+ sys("make install")
24
+ end
25
+ end
26
+
27
+ libgpg_error_tgz = File.join(SRC, 'libgpg-error-1.10.tar.bz2')
28
+ libassuan_tgz = File.join(SRC, 'libassuan-2.0.2.tar.bz2')
29
+ gpgme_tgz = File.join(SRC, 'gpgme-1.3.1.tar.bz2')
30
+
31
+ # build deps
32
+
33
+ build(libgpg_error_tgz, "--disable-nls")
34
+ build(libassuan_tgz, "--with-gpg-error-prefix=#{PREFIX}")
35
+ build(gpgme_tgz, "--with-gpg-error-prefix=#{PREFIX}", "--with-libassuan-prefix=#{PREFIX}")
36
+
37
+ # copy gpgme
38
+
39
+
40
+ %w[ libassuan libgpg-error libgpgme ].each do |lib|
41
+ FileUtils.cp "#{PREFIX}/lib/#{lib}.a", "#{BUILD}/#{lib}_ext.a"
42
+ end
43
+
44
+ $INCFLAGS[0,0] = " -I#{PREFIX}/include "
45
+ #$LDFLAGS << " -L#{PREFIX}/lib "
46
+ $CFLAGS << " -fPIC "
47
+
48
+ # build gpgme extension
49
+
50
+ unless have_library 'gpg-error_ext' and have_library 'gpgme_ext' and have_library 'assuan_ext' and have_library 'gpg-error_ext' and have_header 'gpgme.h'
51
+ STDERR.puts "\n\n"
52
+ STDERR.puts "*********************************************************"
53
+ STDERR.puts "********* error compiling and linking libgpgme. *********"
54
+ STDERR.puts "*********************************************************"
55
+ exit(1)
56
+ end
57
+
58
+ create_makefile ('gpgme_n')
@@ -228,7 +228,7 @@ rb_s_gpgme_data_new (VALUE dummy, VALUE rdh)
228
228
  if (gpgme_err_code(err) == GPG_ERR_NO_ERROR)
229
229
  rb_ary_store (rdh, 0, WRAP_GPGME_DATA(dh));
230
230
  return LONG2NUM(err);
231
- }
231
+ }
232
232
 
233
233
  static VALUE
234
234
  rb_s_gpgme_data_new_from_mem (VALUE dummy, VALUE rdh, VALUE vbuffer,
@@ -249,7 +249,7 @@ rb_s_gpgme_data_new_from_mem (VALUE dummy, VALUE rdh, VALUE vbuffer,
249
249
  rb_ary_store (rdh, 0, vdh);
250
250
  }
251
251
  return LONG2NUM(err);
252
- }
252
+ }
253
253
 
254
254
  static VALUE
255
255
  rb_s_gpgme_data_new_from_fd (VALUE dummy, VALUE rdh, VALUE vfd)
@@ -494,7 +494,7 @@ rb_s_gpgme_set_textmode (VALUE dummy, VALUE vctx, VALUE vyes)
494
494
  rb_raise (rb_eArgError, "released ctx");
495
495
  gpgme_set_textmode (ctx, NUM2INT(vyes));
496
496
  return Qnil;
497
- }
497
+ }
498
498
 
499
499
  static VALUE
500
500
  rb_s_gpgme_get_textmode (VALUE dummy, VALUE vctx)
@@ -507,7 +507,7 @@ rb_s_gpgme_get_textmode (VALUE dummy, VALUE vctx)
507
507
  rb_raise (rb_eArgError, "released ctx");
508
508
  yes = gpgme_get_textmode (ctx);
509
509
  return INT2FIX(yes);
510
- }
510
+ }
511
511
 
512
512
  static VALUE
513
513
  rb_s_gpgme_set_include_certs (VALUE dummy, VALUE vctx, VALUE vnr_of_certs)
@@ -609,7 +609,7 @@ rb_s_gpgme_get_passphrase_cb (VALUE dummy, VALUE vctx, VALUE rpassfunc,
609
609
  return Qnil;
610
610
  }
611
611
 
612
- static void
612
+ static void
613
613
  progress_cb (void *hook, const char *what, int type, int current, int total)
614
614
  {
615
615
  VALUE vcb = (VALUE)hook, vprogfunc, vhook_value;
@@ -657,7 +657,7 @@ rb_s_gpgme_set_locale (VALUE dummy, VALUE vctx, VALUE vcategory, VALUE vvalue)
657
657
  {
658
658
  gpgme_ctx_t ctx;
659
659
  gpgme_error_t err;
660
-
660
+
661
661
  UNWRAP_GPGME_CTX(vctx, ctx);
662
662
  if (!ctx)
663
663
  rb_raise (rb_eArgError, "released ctx");
@@ -1518,7 +1518,7 @@ rb_s_gpgme_op_verify_result (VALUE dummy, VALUE vctx)
1518
1518
  gpgme_verify_result_t verify_result;
1519
1519
  gpgme_signature_t signature;
1520
1520
  VALUE vverify_result, vsignatures = rb_ary_new ();
1521
-
1521
+
1522
1522
  UNWRAP_GPGME_CTX(vctx, ctx);
1523
1523
  if (!ctx)
1524
1524
  rb_raise (rb_eArgError, "released ctx");
@@ -1924,7 +1924,7 @@ rb_s_gpgme_wait (VALUE dummy, VALUE vctx, VALUE rstatus, VALUE vhang)
1924
1924
  return Qnil;
1925
1925
  }
1926
1926
 
1927
- void
1927
+ void
1928
1928
  Init_gpgme_n (void)
1929
1929
  {
1930
1930
  VALUE mGPGME;
@@ -1,1561 +1,108 @@
1
- =begin rdoc
2
- = What's this?
3
-
4
- Ruby-GPGME is a Ruby language binding of GPGME (GnuPG Made Easy).
5
-
6
- = Requirements
7
-
8
- - Ruby 1.8 or later
9
- - GPGME 1.1.2 or later http://www.gnupg.org/(en)/related_software/gpgme/index.html
10
- - gpg-agent (optional, but recommended)
11
-
12
- = Installation
13
-
14
- $ gem install ruby-gpgme
15
-
16
- or
17
-
18
- $ ruby extconf.rb
19
- $ make
20
- $ make install
21
-
22
- = Examples
23
-
24
- <tt>examples/genkey.rb</tt>:: Generate a key pair in your keyring.
25
- <tt>examples/keylist.rb</tt>:: List your keyring like gpg --list-keys.
26
- <tt>examples/roundtrip.rb</tt>:: Encrypt and decrypt a plain text.
27
- <tt>examples/sign.rb</tt>:: Create a clear text signature.
28
- <tt>examples/verify.rb</tt>:: Verify a clear text signature given from stdin.
29
-
30
- = API
31
-
32
- Ruby-GPGME provides three levels of API. The highest level API is
33
- close to the command line interface of GnuPG. The mid level API looks
34
- object-oriented (or rubyish). The lowest level API is close to the C
35
- interface of GPGME.
36
-
37
- == The highest level API
38
-
39
- It can be written in the highest level API to create a cleartext
40
- signature of the plaintext from stdin as follows.
41
-
42
- $ ruby -rgpgme -e 'GPGME.clearsign($stdin, $stdout)'
43
-
44
- == The mid level API
45
-
46
- The same example can be rewritten in the mid level API as follows.
47
-
48
- $ ruby -rgpgme -e <<End
49
- ctx = GPGME::Ctx.new
50
- plain = GPGME::Data.from_io($stdin)
51
- sig = GPGME::Data.from_io($stdout)
52
- ctx.sign(plain, sig, GPGME::SIG_MODE_CLEAR)
53
- End
54
-
55
- == The lowest level API
56
-
57
- The same example can be rewritten in the lowest level API as follows.
58
-
59
- $ ruby -rgpgme -e <<End
60
- ret = Array.new
61
- GPGME::gpgme_new(ret)
62
- ctx = ret.shift
63
- GPGME::gpgme_data_new_from_fd(ret, 0)
64
- plain = ret.shift
65
- GPGME::gpgme_data_new_from_fd(ret, 1)
66
- sig = ret.shift
67
- GPGME::gpgme_op_sign(ctx, plain, sig, GPGME::SIG_MODE_CLEAR)
68
- End
69
-
70
- As you see, it's much harder to write a program in this API than the
71
- higher level API. However, if you are already familier with the C
72
- interface of GPGME and/or want to control detailed behavior of GPGME,
73
- it might be useful.
74
-
75
- = License
76
-
77
- Copyright (C) 2003,2006,2007,2008,2009 Daiki Ueno
78
-
79
- This file is a part of Ruby-GPGME.
80
-
81
- Ruby-GPGME is free software; you can redistribute it and/or
82
- modify it under the terms of the GNU Lesser General Public
83
- License as published by the Free Software Foundation; either
84
- version 2.1 of the License, or (at your option) any later version.
85
-
86
- Ruby-GPGME is distributed in the hope that it will be useful,
87
- but WITHOUT ANY WARRANTY; without even the implied warranty of
88
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
89
- Lesser General Public License for more details.
90
-
91
- You should have received a copy of the GNU Lesser General Public
92
- License along with this library; if not, write to the Free Software
93
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
94
- =end
95
- module GPGME
96
- VERSION = "1.0.8"
97
- end
1
+ $:.push File.expand_path("../..", __FILE__) # C extension is in the root
98
2
 
99
3
  require 'gpgme_n'
100
- require 'gpgme/constants'
101
-
102
- # call-seq:
103
- # GPGME.decrypt(cipher, plain=nil, options=Hash.new){|signature| ...}
104
- #
105
- # <code>GPGME.decrypt</code> performs decryption.
106
- #
107
- # The arguments should be specified as follows.
108
- #
109
- # - GPGME.decrypt(<i>cipher</i>, <i>plain</i>, <i>options</i>)
110
- # - GPGME.decrypt(<i>cipher</i>, <i>options</i>) -> <i>plain</i>
111
- #
112
- # All arguments except <i>cipher</i> are optional. <i>cipher</i> is
113
- # input, and <i>plain</i> is output. If the last argument is a
114
- # Hash, options will be read from it.
115
- #
116
- # An input argument is specified by an IO like object (which responds
117
- # to <code>read</code>), a string, or a GPGME::Data object.
118
- #
119
- # An output argument is specified by an IO like object (which responds
120
- # to <code>write</code>) or a GPGME::Data object.
121
- #
122
- # <i>options</i> are same as <code>GPGME::Ctx.new()</code>.
123
- #
124
- def GPGME.decrypt(cipher, *args_options)
125
- raise ArgumentError, 'wrong number of arguments' if args_options.length > 2
126
- args, options = split_args(args_options)
127
- plain = args[0]
128
-
129
- check_version(options)
130
- GPGME::Ctx.new(options) do |ctx|
131
- cipher_data = input_data(cipher)
132
- plain_data = output_data(plain)
133
- begin
134
- ctx.decrypt_verify(cipher_data, plain_data)
135
- rescue GPGME::Error::UnsupportedAlgorithm => exc
136
- exc.algorithm = ctx.decrypt_result.unsupported_algorithm
137
- raise exc
138
- rescue GPGME::Error::WrongKeyUsage => exc
139
- exc.key_usage = ctx.decrypt_result.wrong_key_usage
140
- raise exc
141
- end
142
-
143
- verify_result = ctx.verify_result
144
- if verify_result && block_given?
145
- verify_result.signatures.each do |signature|
146
- yield signature
147
- end
148
- end
149
-
150
- unless plain
151
- plain_data.seek(0, IO::SEEK_SET)
152
- plain_data.read
153
- end
154
- end
155
- end
156
-
157
- # call-seq:
158
- # GPGME.verify(sig, signed_text=nil, plain=nil, options=Hash.new){|signature| ...}
159
- #
160
- # <code>GPGME.verify</code> verifies a signature.
161
- #
162
- # The arguments should be specified as follows.
163
- #
164
- # - GPGME.verify(<i>sig</i>, <i>signed_text</i>, <i>plain</i>, <i>options</i>)
165
- # - GPGME.verify(<i>sig</i>, <i>signed_text</i>, <i>options</i>) -> <i>plain</i>
166
- #
167
- # All arguments except <i>sig</i> are optional. <i>sig</i> and
168
- # <i>signed_text</i> are input. <i>plain</i> is output. If the last
169
- # argument is a Hash, options will be read from it.
170
- #
171
- # An input argument is specified by an IO like object (which responds
172
- # to <code>read</code>), a string, or a GPGME::Data object.
173
- #
174
- # An output argument is specified by an IO like object (which responds
175
- # to <code>write</code>) or a GPGME::Data object.
176
- #
177
- # If <i>sig</i> is a detached signature, then the signed text should
178
- # be provided in <i>signed_text</i> and <i>plain</i> should be
179
- # <tt>nil</tt>. Otherwise, if <i>sig</i> is a normal (or cleartext)
180
- # signature, <i>signed_text</i> should be <tt>nil</tt>.
181
- #
182
- # <i>options</i> are same as <code>GPGME::Ctx.new()</code>.
183
- #
184
- def GPGME.verify(sig, *args_options) # :yields: signature
185
- raise ArgumentError, 'wrong number of arguments' if args_options.length > 3
186
- args, options = split_args(args_options)
187
- signed_text, plain = args
188
-
189
- check_version(options)
190
- GPGME::Ctx.new(options) do |ctx|
191
- sig_data = input_data(sig)
192
- if signed_text
193
- signed_text_data = input_data(signed_text)
194
- plain_data = nil
195
- else
196
- signed_text_data = nil
197
- plain_data = output_data(plain)
198
- end
199
- ctx.verify(sig_data, signed_text_data, plain_data)
200
- ctx.verify_result.signatures.each do |signature|
201
- yield signature
202
- end
203
- if !signed_text && !plain
204
- plain_data.seek(0, IO::SEEK_SET)
205
- plain_data.read
206
- end
207
- end
208
- end
209
-
210
- # call-seq:
211
- # GPGME.sign(plain, sig=nil, options=Hash.new)
212
- #
213
- # <code>GPGME.sign</code> creates a signature of the plaintext.
214
- #
215
- # The arguments should be specified as follows.
216
- #
217
- # - GPGME.sign(<i>plain</i>, <i>sig</i>, <i>options</i>)
218
- # - GPGME.sign(<i>plain</i>, <i>options</i>) -> <i>sig</i>
219
- #
220
- # All arguments except <i>plain</i> are optional. <i>plain</i> is
221
- # input and <i>sig</i> is output. If the last argument is a Hash,
222
- # options will be read from it.
223
- #
224
- # An input argument is specified by an IO like object (which responds
225
- # to <code>read</code>), a string, or a GPGME::Data object.
226
- #
227
- # An output argument is specified by an IO like object (which responds
228
- # to <code>write</code>) or a GPGME::Data object.
229
- #
230
- # <i>options</i> are same as <code>GPGME::Ctx.new()</code> except for
231
- #
232
- # - <tt>:signers</tt> Signing keys. If specified, it is an array
233
- # whose elements are a GPGME::Key object or a string.
234
- # - <tt>:mode</tt> Desired type of a signature. Either
235
- # <tt>GPGME::SIG_MODE_NORMAL</tt> for a normal signature,
236
- # <tt>GPGME::SIG_MODE_DETACH</tt> for a detached signature, or
237
- # <tt>GPGME::SIG_MODE_CLEAR</tt> for a cleartext signature.
238
- #
239
- def GPGME.sign(plain, *args_options)
240
- raise ArgumentError, 'wrong number of arguments' if args_options.length > 2
241
- args, options = split_args(args_options)
242
- sig = args[0]
243
-
244
- check_version(options)
245
- GPGME::Ctx.new(options) do |ctx|
246
- ctx.add_signer(*resolve_keys(options[:signers], true, [:sign])) if options[:signers]
247
- mode = options[:mode] || GPGME::SIG_MODE_NORMAL
248
- plain_data = input_data(plain)
249
- sig_data = output_data(sig)
250
- begin
251
- ctx.sign(plain_data, sig_data, mode)
252
- rescue GPGME::Error::UnusableSecretKey => exc
253
- exc.keys = ctx.sign_result.invalid_signers
254
- raise exc
255
- end
256
-
257
- unless sig
258
- sig_data.seek(0, IO::SEEK_SET)
259
- sig_data.read
260
- end
261
- end
262
- end
263
-
264
- # call-seq:
265
- # GPGME.clearsign(plain, sig=nil, options=Hash.new)
266
- #
267
- # <code>GPGME.clearsign</code> creates a cleartext signature of the plaintext.
268
- #
269
- # The arguments should be specified as follows.
270
- #
271
- # - GPGME.clearsign(<i>plain</i>, <i>sig</i>, <i>options</i>)
272
- # - GPGME.clearsign(<i>plain</i>, <i>options</i>) -> <i>sig</i>
273
- #
274
- # All arguments except <i>plain</i> are optional. <i>plain</i> is
275
- # input and <i>sig</i> is output. If the last argument is a Hash,
276
- # options will be read from it.
277
- #
278
- # An input argument is specified by an IO like object (which responds
279
- # to <code>read</code>), a string, or a GPGME::Data object.
280
- #
281
- # An output argument is specified by an IO like object (which responds
282
- # to <code>write</code>) or a GPGME::Data object.
283
- #
284
- # <i>options</i> are same as <code>GPGME::Ctx.new()</code> except for
285
- #
286
- # - <tt>:signers</tt> Signing keys. If specified, it is an array
287
- # whose elements are a GPGME::Key object or a string.
288
- #
289
- def GPGME.clearsign(plain, *args_options)
290
- raise ArgumentError, 'wrong number of arguments' if args_options.length > 2
291
- args, options = split_args(args_options)
292
- args.push(options.merge({:mode => GPGME::SIG_MODE_CLEAR}))
293
- GPGME.sign(plain, *args)
294
- end
295
-
296
- # call-seq:
297
- # GPGME.detach_sign(plain, sig=nil, options=Hash.new)
298
- #
299
- # <code>GPGME.detach_sign</code> creates a detached signature of the plaintext.
300
- #
301
- # The arguments should be specified as follows.
302
- #
303
- # - GPGME.detach_sign(<i>plain</i>, <i>sig</i>, <i>options</i>)
304
- # - GPGME.detach_sign(<i>plain</i>, <i>options</i>) -> <i>sig</i>
305
- #
306
- # All arguments except <i>plain</i> are optional. <i>plain</i> is
307
- # input and <i>sig</i> is output. If the last argument is a Hash,
308
- # options will be read from it.
309
- #
310
- # An input argument is specified by an IO like object (which responds
311
- # to <code>read</code>), a string, or a GPGME::Data object.
312
- #
313
- # An output argument is specified by an IO like object (which responds
314
- # to <code>write</code>) or a GPGME::Data object.
315
- #
316
- # <i>options</i> are same as <code>GPGME::Ctx.new()</code> except for
317
- #
318
- # - <tt>:signers</tt> Signing keys. If specified, it is an array
319
- # whose elements are a GPGME::Key object or a string.
320
- #
321
- def GPGME.detach_sign(plain, *args_options)
322
- raise ArgumentError, 'wrong number of arguments' if args_options.length > 2
323
- args, options = split_args(args_options)
324
- args.push(options.merge({:mode => GPGME::SIG_MODE_DETACH}))
325
- GPGME.sign(plain, *args)
326
- end
327
-
328
- # call-seq:
329
- # GPGME.encrypt(recipients, plain, cipher=nil, options=Hash.new)
330
- #
331
- # <code>GPGME.encrypt</code> performs encryption.
332
- #
333
- # The arguments should be specified as follows.
334
- #
335
- # - GPGME.encrypt(<i>recipients</i>, <i>plain</i>, <i>cipher</i>, <i>options</i>)
336
- # - GPGME.encrypt(<i>recipients</i>, <i>plain</i>, <i>options</i>) -> <i>cipher</i>
337
- #
338
- # All arguments except <i>recipients</i> and <i>plain</i> are
339
- # optional. <i>plain</i> is input and <i>cipher</i> is output. If
340
- # the last argument is a Hash, options will be read from it.
341
- #
342
- # The recipients are specified by an array whose elements are a string
343
- # or a GPGME::Key object. If <i>recipients</i> is <tt>nil</tt>, it
344
- # performs symmetric encryption.
345
- #
346
- # An input argument is specified by an IO like object (which responds
347
- # to <code>read</code>), a string, or a GPGME::Data object.
348
- #
349
- # An output argument is specified by an IO like object (which responds
350
- # to <code>write</code>) or a GPGME::Data object.
351
- #
352
- # <i>options</i> are same as <code>GPGME::Ctx.new()</code> except for
353
- #
354
- # - <tt>:sign</tt> If <tt>true</tt>, it performs a combined sign and
355
- # encrypt operation.
356
- # - <tt>:signers</tt> Signing keys. If specified, it is an array
357
- # whose elements are a GPGME::Key object or a string.
358
- # - <tt>:always_trust</tt> Setting this to <tt>true</tt> specifies all
359
- # the recipients should be trusted.
360
- #
361
- def GPGME.encrypt(recipients, plain, *args_options)
362
- raise ArgumentError, 'wrong number of arguments' if args_options.length > 3
363
- args, options = split_args(args_options)
364
- cipher = args[0]
365
- recipient_keys = recipients ? resolve_keys(recipients, false, [:encrypt]) : nil
366
-
367
- check_version(options)
368
- GPGME::Ctx.new(options) do |ctx|
369
- plain_data = input_data(plain)
370
- cipher_data = output_data(cipher)
371
- begin
372
- flags = 0
373
- if options[:always_trust]
374
- flags |= GPGME::ENCRYPT_ALWAYS_TRUST
375
- end
376
- if options[:sign]
377
- if options[:signers]
378
- ctx.add_signer(*resolve_keys(options[:signers], true, [:sign]))
379
- end
380
- ctx.encrypt_sign(recipient_keys, plain_data, cipher_data, flags)
381
- else
382
- ctx.encrypt(recipient_keys, plain_data, cipher_data, flags)
383
- end
384
- rescue GPGME::Error::UnusablePublicKey => exc
385
- exc.keys = ctx.encrypt_result.invalid_recipients
386
- raise exc
387
- rescue GPGME::Error::UnusableSecretKey => exc
388
- exc.keys = ctx.sign_result.invalid_signers
389
- raise exc
390
- end
391
-
392
- unless cipher
393
- cipher_data.seek(0, IO::SEEK_SET)
394
- cipher_data.read
395
- end
396
- end
397
- end
398
-
399
- # call-seq:
400
- # GPGME.list_keys(pattern=nil, secret_only=false, options=Hash.new){|key| ...}
401
- #
402
- # <code>GPGME.list_keys</code> iterates over the key ring.
403
- #
404
- # The arguments should be specified as follows.
405
- #
406
- # - GPGME.list_keys(<i>pattern</i>, <i>secret_only</i>, <i>options</i>)
407
- #
408
- # All arguments are optional. If the last argument is a Hash, options
409
- # will be read from it.
410
- #
411
- # <i>pattern</i> is a string or <tt>nil</tt>. If <i>pattern</i> is
412
- # <tt>nil</tt>, all available keys are returned. If
413
- # <i>secret_only</i> is <tt>true</tt>, the only secret keys are
414
- # returned.
415
- #
416
- # <i>options</i> are same as <code>GPGME::Ctx.new()</code>.
417
- #
418
- def GPGME.list_keys(*args_options) # :yields: key
419
- raise ArgumentError, 'wrong number of arguments' if args_options.length > 3
420
- args, options = split_args(args_options)
421
- pattern, secret_only = args
422
- check_version(options)
423
- GPGME::Ctx.new do |ctx|
424
- if block_given?
425
- ctx.each_key(pattern, secret_only || false) do |key|
426
- yield key
427
- end
428
- else
429
- ctx.keys(pattern, secret_only || false)
430
- end
431
- end
432
- end
433
-
434
- # call-seq:
435
- # GPGME.export(pattern)
436
- #
437
- # <code>GPGME.export</code> extracts public keys from the key ring.
438
- #
439
- # The arguments should be specified as follows.
440
- #
441
- # - GPGME.export(<i>pattern</i>, <i>options</i>) -> <i>keydata</i>
442
- # - GPGME.export(<i>pattern</i>, <i>keydata</i>, <i>options</i>)
443
- #
444
- # All arguments are optional. If the last argument is a Hash, options
445
- # will be read from it.
446
- #
447
- # <i>pattern</i> is a string or <tt>nil</tt>. If <i>pattern</i> is
448
- # <tt>nil</tt>, all available public keys are returned.
449
- # <i>keydata</i> is output.
450
- #
451
- # An output argument is specified by an IO like object (which responds
452
- # to <code>write</code>) or a GPGME::Data object.
453
- #
454
- # <i>options</i> are same as <code>GPGME::Ctx.new()</code>.
455
- #
456
- def GPGME.export(*args_options)
457
- raise ArgumentError, 'wrong number of arguments' if args_options.length > 2
458
- args, options = split_args(args_options)
459
- pattern, key = args[0]
460
- key_data = output_data(key)
461
- check_version(options)
462
- GPGME::Ctx.new(options) do |ctx|
463
- ctx.export_keys(pattern, key_data)
464
-
465
- unless key
466
- key_data.seek(0, IO::SEEK_SET)
467
- key_data.read
468
- end
469
- end
470
- end
471
-
472
- # call-seq:
473
- # GPGME.import(keydata)
474
- #
475
- # <code>GPGME.import</code> adds the keys to the key ring.
476
- #
477
- # The arguments should be specified as follows.
478
- #
479
- # - GPGME.import(<i>keydata</i>, <i>options</i>)
480
- #
481
- # All arguments are optional. If the last argument is a Hash, options
482
- # will be read from it.
483
- #
484
- # <i>keydata</i> is input.
485
- #
486
- # An input argument is specified by an IO like object (which responds
487
- # to <code>read</code>), a string, or a GPGME::Data object.
488
- #
489
- # <i>options</i> are same as <code>GPGME::Ctx.new()</code>.
490
- #
491
- def GPGME.import(*args_options)
492
- raise ArgumentError, 'wrong number of arguments' if args_options.length > 2
493
- args, options = split_args(args_options)
494
- key = args[0]
495
- key_data = input_data(key)
496
- check_version(options)
497
- GPGME::Ctx.new(options) do |ctx|
498
- ctx.import_keys(key_data)
499
- ctx.import_result
500
- end
501
- end
502
-
503
- module GPGME
504
- # :stopdoc:
505
- private
506
-
507
- def split_args(args_options)
508
- if args_options.length > 0 and args_options[-1].respond_to? :to_hash
509
- args = args_options[0 ... -1]
510
- options = args_options[-1].to_hash
511
- else
512
- args = args_options
513
- options = Hash.new
514
- end
515
- [args, options]
516
- end
517
- module_function :split_args
518
4
 
519
- def check_version(options = nil)
520
- version = nil
521
- if options.kind_of?(String)
522
- version = options
523
- elsif options.include?(:version)
524
- version = options[:version]
525
- end
526
- unless GPGME::gpgme_check_version(version)
527
- raise Error::InvalidVersion.new
528
- end
529
- end
530
- module_function :check_version
531
-
532
- def resolve_keys(keys_or_names, secret_only, purposes = Array.new)
533
- keys = Array.new
534
- keys_or_names.each do |key_or_name|
535
- if key_or_name.kind_of? Key
536
- keys << key_or_name
537
- elsif key_or_name.kind_of? String
538
- GPGME::Ctx.new do |ctx|
539
- key = ctx.keys(key_or_name, secret_only).find {|k|
540
- k.usable_for?(purposes)
541
- }
542
- keys << key if key
543
- end
544
- end
545
- end
546
- keys
547
- end
548
- module_function :resolve_keys
549
-
550
- def input_data(input)
551
- if input.kind_of? GPGME::Data
552
- input
553
- elsif input.respond_to? :to_str
554
- GPGME::Data.from_str(input.to_str)
555
- elsif input.respond_to? :read
556
- GPGME::Data.from_callbacks(IOCallbacks.new(input))
557
- else
558
- raise ArgumentError, input.inspect
559
- end
560
- end
561
- module_function :input_data
562
-
563
- def output_data(output)
564
- if output.kind_of? GPGME::Data
565
- output
566
- elsif output.respond_to? :write
567
- GPGME::Data.from_callbacks(IOCallbacks.new(output))
568
- elsif !output
569
- GPGME::Data.empty
570
- else
571
- raise ArgumentError, output.inspect
572
- end
573
- end
574
- module_function :output_data
575
-
576
- class IOCallbacks
577
- def initialize(io)
578
- @io = io
579
- end
580
-
581
- def read(hook, length)
582
- @io.read(length)
583
- end
584
-
585
- def write(hook, buffer, length)
586
- @io.write(buffer[0 .. length])
587
- end
588
-
589
- def seek(hook, offset, whence)
590
- return @io.pos if offset == 0 && whence == IO::SEEK_CUR
591
- @io.seek(offset, whence)
592
- @io.pos
593
- end
594
- end
5
+ # TODO without this call one can't GPGME::Ctx.new, find out why
6
+ GPGME::gpgme_check_version(nil)
595
7
 
596
- PROTOCOL_NAMES = {
597
- PROTOCOL_OpenPGP => :OpenPGP,
598
- PROTOCOL_CMS => :CMS
599
- }
600
-
601
- KEYLIST_MODE_NAMES = {
602
- KEYLIST_MODE_LOCAL => :local,
603
- KEYLIST_MODE_EXTERN => :extern,
604
- KEYLIST_MODE_SIGS => :sigs,
605
- KEYLIST_MODE_VALIDATE => :validate
606
- }
607
-
608
- VALIDITY_NAMES = {
609
- VALIDITY_UNKNOWN => :unknown,
610
- VALIDITY_UNDEFINED => :undefined,
611
- VALIDITY_NEVER => :never,
612
- VALIDITY_MARGINAL => :marginal,
613
- VALIDITY_FULL => :full,
614
- VALIDITY_ULTIMATE => :ultimate
615
- }
616
- # :startdoc:
617
- end
8
+ require 'gpgme/constants'
9
+ require 'gpgme/ctx'
10
+ require 'gpgme/data'
11
+ require 'gpgme/error'
12
+ require 'gpgme/io_callbacks'
13
+ require 'gpgme/key_common'
14
+ require 'gpgme/key'
15
+ require 'gpgme/sub_key'
16
+ require 'gpgme/key_sig'
17
+ require 'gpgme/misc'
18
+ require 'gpgme/signature'
19
+ require 'gpgme/user_id'
20
+ require 'gpgme/engine'
21
+ require 'gpgme/crypto'
618
22
 
619
23
  module GPGME
620
- class Error < StandardError
621
- def initialize(error)
622
- @error = error
623
- end
624
- attr_reader :error
625
-
626
- # Return the error code.
627
- #
628
- # The error code indicates the type of an error, or the reason why
629
- # an operation failed.
630
- def code
631
- GPGME::gpgme_err_code(@error)
632
- end
633
-
634
- # Return the error source.
635
- #
636
- # The error source has not a precisely defined meaning. Sometimes
637
- # it is the place where the error happened, sometimes it is the
638
- # place where an error was encoded into an error value. Usually
639
- # the error source will give an indication to where to look for
640
- # the problem. This is not always true, but it is attempted to
641
- # achieve this goal.
642
- def source
643
- GPGME::gpgme_err_source(@error)
644
- end
645
-
646
- # Return a description of the error code.
647
- def message
648
- GPGME::gpgme_strerror(@error)
649
- end
650
-
651
- class General < self; end
652
- class InvalidValue < self; end
653
- class UnusablePublicKey < self
654
- attr_accessor :keys
655
- end
656
- class UnusableSecretKey < self
657
- attr_accessor :keys
658
- end
659
- class NoData < self; end
660
- class Conflict < self; end
661
- class NotImplemented < self; end
662
- class DecryptFailed < self; end
663
- class BadPassphrase < self; end
664
- class Canceled < self; end
665
- class InvalidEngine < self; end
666
- class AmbiguousName < self; end
667
- class WrongKeyUsage < self
668
- attr_accessor :key_usage
669
- end
670
- class CertificateRevoked < self; end
671
- class CertificateExpired < self; end
672
- class NoCRLKnown < self; end
673
- class NoPolicyMatch < self; end
674
- class NoSecretKey < self; end
675
- class MissingCertificate < self; end
676
- class BadCertificateChain < self; end
677
- class UnsupportedAlgorithm < self
678
- attr_accessor :algorithm
679
- end
680
- class BadSignature < self; end
681
- class NoPublicKey < self; end
682
- class InvalidVersion < self; end
683
- end
684
-
685
- def error_to_exception(err) # :nodoc:
686
- case GPGME::gpgme_err_code(err)
687
- when GPG_ERR_EOF
688
- EOFError.new
689
- when GPG_ERR_NO_ERROR
690
- nil
691
- when GPG_ERR_GENERAL
692
- Error::General.new(err)
693
- when GPG_ERR_ENOMEM
694
- Errno::ENOMEM.new
695
- when GPG_ERR_INV_VALUE
696
- Error::InvalidValue.new(err)
697
- when GPG_ERR_UNUSABLE_PUBKEY
698
- Error::UnusablePublicKey.new(err)
699
- when GPG_ERR_UNUSABLE_SECKEY
700
- Error::UnusableSecretKey.new(err)
701
- when GPG_ERR_NO_DATA
702
- Error::NoData.new(err)
703
- when GPG_ERR_CONFLICT
704
- Error::Conflict.new(err)
705
- when GPG_ERR_NOT_IMPLEMENTED
706
- Error::NotImplemented.new(err)
707
- when GPG_ERR_DECRYPT_FAILED
708
- Error::DecryptFailed.new(err)
709
- when GPG_ERR_BAD_PASSPHRASE
710
- Error::BadPassphrase.new(err)
711
- when GPG_ERR_CANCELED
712
- Error::Canceled.new(err)
713
- when GPG_ERR_INV_ENGINE
714
- Error::InvalidEngine.new(err)
715
- when GPG_ERR_AMBIGUOUS_NAME
716
- Error::AmbiguousName.new(err)
717
- when GPG_ERR_WRONG_KEY_USAGE
718
- Error::WrongKeyUsage.new(err)
719
- when GPG_ERR_CERT_REVOKED
720
- Error::CertificateRevoked.new(err)
721
- when GPG_ERR_CERT_EXPIRED
722
- Error::CertificateExpired.new(err)
723
- when GPG_ERR_NO_CRL_KNOWN
724
- Error::NoCRLKnown.new(err)
725
- when GPG_ERR_NO_POLICY_MATCH
726
- Error::NoPolicyMatch.new(err)
727
- when GPG_ERR_NO_SECKEY
728
- Error::NoSecretKey.new(err)
729
- when GPG_ERR_MISSING_CERT
730
- Error::MissingCertificate.new(err)
731
- when GPG_ERR_BAD_CERT_CHAIN
732
- Error::BadCertificateChain.new(err)
733
- when GPG_ERR_UNSUPPORTED_ALGORITHM
734
- Error::UnsupportedAlgorithm.new(err)
735
- when GPG_ERR_BAD_SIGNATURE
736
- Error::BadSignature.new(err)
737
- when GPG_ERR_NO_PUBKEY
738
- Error::NoPublicKey.new(err)
739
- else
740
- Error.new(err)
741
- end
742
- end
743
- module_function :error_to_exception
744
- private :error_to_exception
745
-
746
24
  class << self
25
+
26
+ # From the c extension
747
27
  alias pubkey_algo_name gpgme_pubkey_algo_name
748
28
  alias hash_algo_name gpgme_hash_algo_name
749
- end
750
-
751
- # Verify that the engine implementing the protocol <i>proto</i> is
752
- # installed in the system.
753
- def engine_check_version(proto)
754
- err = GPGME::gpgme_engine_check_version(proto)
755
- exc = GPGME::error_to_exception(err)
756
- raise exc if exc
757
- end
758
- module_function :engine_check_version
759
-
760
- # Return a list of info structures of enabled engines.
761
- def engine_info
762
- rinfo = Array.new
763
- GPGME::gpgme_get_engine_info(rinfo)
764
- rinfo
765
- end
766
- module_function :engine_info
767
-
768
- # Change the default configuration of the crypto engine implementing
769
- # protocol <i>proto</i>.
770
- #
771
- # <i>file_name</i> is the file name of the executable program
772
- # implementing the protocol.
773
- # <i>home_dir</i> is the directory name of the configuration directory.
774
- def set_engine_info(proto, file_name, home_dir)
775
- err = GPGME::gpgme_set_engine_info(proto, file_name, home_dir)
776
- exc = GPGME::error_to_exception(err)
777
- raise exc if exc
778
- end
779
- module_function :set_engine_info
780
-
781
- # A class for managing data buffers.
782
- class Data
783
- BLOCK_SIZE = 4096
784
-
785
- # Create a new instance.
786
- #
787
- # The created data types depend on <i>arg</i>. If <i>arg</i> is
788
- # <tt>nil</tt>, it creates an instance with an empty buffer.
789
- # Otherwise, <i>arg</i> is either a string, an IO, or a Pathname.
790
- def self.new(arg = nil, copy = false)
791
- if arg.nil?
792
- return empty
793
- elsif arg.respond_to? :to_str
794
- return from_str(arg.to_str, copy)
795
- elsif arg.respond_to? :to_io
796
- return from_io(arg.to_io)
797
- elsif arg.respond_to? :open
798
- return from_io(arg.open)
799
- end
800
- end
801
-
802
- # Create a new instance with an empty buffer.
803
- def self.empty
804
- rdh = Array.new
805
- err = GPGME::gpgme_data_new(rdh)
806
- exc = GPGME::error_to_exception(err)
807
- raise exc if exc
808
- rdh[0]
809
- end
810
-
811
- # Create a new instance with internal buffer.
812
- def self.from_str(buf, copy = true)
813
- rdh = Array.new
814
- err = GPGME::gpgme_data_new_from_mem(rdh, buf, buf.length)
815
- exc = GPGME::error_to_exception(err)
816
- raise exc if exc
817
- rdh[0]
818
- end
819
-
820
- # Create a new instance associated with a given IO.
821
- def self.from_io(io)
822
- from_callbacks(IOCallbacks.new(arg))
823
- end
824
-
825
- # Create a new instance from the specified file descriptor.
826
- def self.from_fd(fd)
827
- rdh = Array.new
828
- err = GPGME::gpgme_data_new_from_fd(rdh, fd)
829
- exc = GPGME::error_to_exception(err)
830
- raise exc if exc
831
- rdh[0]
832
- end
833
-
834
- # Create a new instance from the specified callbacks.
835
- def self.from_callbacks(callbacks, hook_value = nil)
836
- rdh = Array.new
837
- err = GPGME::gpgme_data_new_from_cbs(rdh, callbacks, hook_value)
838
- exc = GPGME::error_to_exception(err)
839
- raise exc if exc
840
- rdh[0]
841
- end
842
29
 
843
- # Read at most <i>length</i> bytes from the data object, or to the end
844
- # of file if <i>length</i> is omitted or is <tt>nil</tt>.
845
- def read(length = nil)
846
- if length
847
- GPGME::gpgme_data_read(self, length)
30
+ ##
31
+ # Auxiliary method used by all the library to generate exceptions
32
+ # from error codes returned by the C extension.
33
+ def error_to_exception(err)
34
+ case GPGME::gpgme_err_code(err)
35
+ when GPG_ERR_EOF
36
+ EOFError.new
37
+ when GPG_ERR_NO_ERROR
38
+ nil
39
+ when GPG_ERR_GENERAL
40
+ Error::General.new(err)
41
+ when GPG_ERR_ENOMEM
42
+ Errno::ENOMEM.new
43
+ when GPG_ERR_INV_VALUE
44
+ Error::InvalidValue.new(err)
45
+ when GPG_ERR_UNUSABLE_PUBKEY
46
+ Error::UnusablePublicKey.new(err)
47
+ when GPG_ERR_UNUSABLE_SECKEY
48
+ Error::UnusableSecretKey.new(err)
49
+ when GPG_ERR_NO_DATA
50
+ Error::NoData.new(err)
51
+ when GPG_ERR_CONFLICT
52
+ Error::Conflict.new(err)
53
+ when GPG_ERR_NOT_IMPLEMENTED
54
+ Error::NotImplemented.new(err)
55
+ when GPG_ERR_DECRYPT_FAILED
56
+ Error::DecryptFailed.new(err)
57
+ when GPG_ERR_BAD_PASSPHRASE
58
+ Error::BadPassphrase.new(err)
59
+ when GPG_ERR_CANCELED
60
+ Error::Canceled.new(err)
61
+ when GPG_ERR_INV_ENGINE
62
+ Error::InvalidEngine.new(err)
63
+ when GPG_ERR_AMBIGUOUS_NAME
64
+ Error::AmbiguousName.new(err)
65
+ when GPG_ERR_WRONG_KEY_USAGE
66
+ Error::WrongKeyUsage.new(err)
67
+ when GPG_ERR_CERT_REVOKED
68
+ Error::CertificateRevoked.new(err)
69
+ when GPG_ERR_CERT_EXPIRED
70
+ Error::CertificateExpired.new(err)
71
+ when GPG_ERR_NO_CRL_KNOWN
72
+ Error::NoCRLKnown.new(err)
73
+ when GPG_ERR_NO_POLICY_MATCH
74
+ Error::NoPolicyMatch.new(err)
75
+ when GPG_ERR_NO_SECKEY
76
+ Error::NoSecretKey.new(err)
77
+ when GPG_ERR_MISSING_CERT
78
+ Error::MissingCertificate.new(err)
79
+ when GPG_ERR_BAD_CERT_CHAIN
80
+ Error::BadCertificateChain.new(err)
81
+ when GPG_ERR_UNSUPPORTED_ALGORITHM
82
+ Error::UnsupportedAlgorithm.new(err)
83
+ when GPG_ERR_BAD_SIGNATURE
84
+ Error::BadSignature.new(err)
85
+ when GPG_ERR_NO_PUBKEY
86
+ Error::NoPublicKey.new(err)
848
87
  else
849
- buf = String.new
850
- loop do
851
- s = GPGME::gpgme_data_read(self, BLOCK_SIZE)
852
- break unless s
853
- buf << s
854
- end
855
- buf
856
- end
857
- end
858
-
859
- # Seek to a given <i>offset</i> in the data object according to the
860
- # value of <i>whence</i>.
861
- def seek(offset, whence = IO::SEEK_SET)
862
- GPGME::gpgme_data_seek(self, offset, IO::SEEK_SET)
863
- end
864
-
865
- # Write <i>length</i> bytes from <i>buffer</i> into the data object.
866
- def write(buffer, length = buffer.length)
867
- GPGME::gpgme_data_write(self, buffer, length)
868
- end
869
-
870
- # Return the encoding of the underlying data.
871
- def encoding
872
- GPGME::gpgme_data_get_encoding(self)
873
- end
874
-
875
- # Set the encoding to a given <i>encoding</i> of the underlying
876
- # data object.
877
- def encoding=(encoding)
878
- err = GPGME::gpgme_data_set_encoding(self, encoding)
879
- exc = GPGME::error_to_exception(err)
880
- raise exc if exc
881
- encoding
882
- end
883
- end
884
-
885
- class EngineInfo
886
- private_class_method :new
887
-
888
- attr_reader :protocol, :file_name, :version, :req_version, :home_dir
889
- alias required_version req_version
890
- end
891
-
892
- # A context within which all cryptographic operations are performed.
893
- class Ctx
894
- # Create a new instance from the given <i>options</i>.
895
- # <i>options</i> is a Hash whose keys are
896
- #
897
- # * <tt>:protocol</tt> Either <tt>PROTOCOL_OpenPGP</tt> or
898
- # <tt>PROTOCOL_CMS</tt>.
899
- #
900
- # * <tt>:armor</tt> If <tt>true</tt>, the output should be ASCII armored.
901
- #
902
- # * <tt>:textmode</tt> If <tt>true</tt>, inform the recipient that the
903
- # input is text.
904
- #
905
- # * <tt>:keylist_mode</tt> Either
906
- # <tt>KEYLIST_MODE_LOCAL</tt>,
907
- # <tt>KEYLIST_MODE_EXTERN</tt>,
908
- # <tt>KEYLIST_MODE_SIGS</tt>, or
909
- # <tt>KEYLIST_MODE_VALIDATE</tt>.
910
- # * <tt>:passphrase_callback</tt> A callback function.
911
- # * <tt>:passphrase_callback_value</tt> An object passed to
912
- # passphrase_callback.
913
- # * <tt>:progress_callback</tt> A callback function.
914
- # * <tt>:progress_callback_value</tt> An object passed to
915
- # progress_callback.
916
- #
917
- def self.new(options = Hash.new)
918
- rctx = Array.new
919
- err = GPGME::gpgme_new(rctx)
920
- exc = GPGME::error_to_exception(err)
921
- raise exc if exc
922
- ctx = rctx[0]
923
- options.each_pair do |key, value|
924
- case key
925
- when :protocol
926
- ctx.protocol = value
927
- when :armor
928
- ctx.armor = value
929
- when :textmode
930
- ctx.textmode = value
931
- when :keylist_mode
932
- ctx.keylist_mode = value
933
- when :passphrase_callback
934
- ctx.set_passphrase_callback(value,
935
- options[:passphrase_callback_value])
936
- when :progress_callback
937
- ctx.set_progress_callback(value,
938
- options[:progress_callback_value])
939
- end
940
- end
941
- if block_given?
942
- begin
943
- yield ctx
944
- ensure
945
- GPGME::gpgme_release(ctx)
946
- end
947
- else
948
- ctx
949
- end
950
- end
951
-
952
- # Set the <i>protocol</i> used within this context.
953
- def protocol=(proto)
954
- err = GPGME::gpgme_set_protocol(self, proto)
955
- exc = GPGME::error_to_exception(err)
956
- raise exc if exc
957
- proto
958
- end
959
-
960
- # Return the protocol used within this context.
961
- def protocol
962
- GPGME::gpgme_get_protocol(self)
963
- end
964
-
965
- # Tell whether the output should be ASCII armored.
966
- def armor=(yes)
967
- GPGME::gpgme_set_armor(self, yes ? 1 : 0)
968
- yes
969
- end
970
-
971
- # Return true if the output is ASCII armored.
972
- def armor
973
- GPGME::gpgme_get_armor(self) == 1 ? true : false
974
- end
975
-
976
- # Tell whether canonical text mode should be used.
977
- def textmode=(yes)
978
- GPGME::gpgme_set_textmode(self, yes ? 1 : 0)
979
- yes
980
- end
981
-
982
- # Return true if canonical text mode is enabled.
983
- def textmode
984
- GPGME::gpgme_get_textmode(self) == 1 ? true : false
985
- end
986
-
987
- # Change the default behaviour of the key listing functions.
988
- def keylist_mode=(mode)
989
- GPGME::gpgme_set_keylist_mode(self, mode)
990
- mode
991
- end
992
-
993
- # Return the current key listing mode.
994
- def keylist_mode
995
- GPGME::gpgme_get_keylist_mode(self)
996
- end
997
-
998
- def inspect
999
- "#<#{self.class} protocol=#{PROTOCOL_NAMES[protocol] || protocol}, \
1000
- armor=#{armor}, textmode=#{textmode}, \
1001
- keylist_mode=#{KEYLIST_MODE_NAMES[keylist_mode]}>"
1002
- end
1003
-
1004
- # Set the passphrase callback with given hook value.
1005
- # <i>passfunc</i> should respond to <code>call</code> with 5 arguments.
1006
- #
1007
- # def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
1008
- # $stderr.write("Passphrase for #{uid_hint}: ")
1009
- # $stderr.flush
1010
- # begin
1011
- # system('stty -echo')
1012
- # io = IO.for_fd(fd, 'w')
1013
- # io.puts(gets)
1014
- # io.flush
1015
- # ensure
1016
- # (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
1017
- # system('stty echo')
1018
- # end
1019
- # $stderr.puts
1020
- # end
1021
- #
1022
- # ctx.set_passphrase_callback(method(:passfunc))
1023
- #
1024
- def set_passphrase_callback(passfunc, hook_value = nil)
1025
- GPGME::gpgme_set_passphrase_cb(self, passfunc, hook_value)
1026
- end
1027
- alias set_passphrase_cb set_passphrase_callback
1028
-
1029
- # Set the progress callback with given hook value.
1030
- # <i>progfunc</i> should respond to <code>call</code> with 5 arguments.
1031
- #
1032
- # def progfunc(hook, what, type, current, total)
1033
- # $stderr.write("#{what}: #{current}/#{total}\r")
1034
- # $stderr.flush
1035
- # end
1036
- #
1037
- # ctx.set_progress_callback(method(:progfunc))
1038
- #
1039
- def set_progress_callback(progfunc, hook_value = nil)
1040
- GPGME::gpgme_set_progress_cb(self, progfunc, hook_value)
1041
- end
1042
- alias set_progress_cb set_progress_callback
1043
-
1044
- # Initiate a key listing operation for given pattern.
1045
- # If <i>pattern</i> is <tt>nil</tt>, all available keys are
1046
- # returned. If <i>secret_only</i> is <tt>true</tt>, the only
1047
- # secret keys are returned.
1048
- def keylist_start(pattern = nil, secret_only = false)
1049
- err = GPGME::gpgme_op_keylist_start(self, pattern, secret_only ? 1 : 0)
1050
- exc = GPGME::error_to_exception(err)
1051
- raise exc if exc
1052
- end
1053
-
1054
- # Advance to the next key in the key listing operation.
1055
- def keylist_next
1056
- rkey = Array.new
1057
- err = GPGME::gpgme_op_keylist_next(self, rkey)
1058
- exc = GPGME::error_to_exception(err)
1059
- raise exc if exc
1060
- rkey[0]
1061
- end
1062
-
1063
- # End a pending key list operation.
1064
- def keylist_end
1065
- err = GPGME::gpgme_op_keylist_end(self)
1066
- exc = GPGME::error_to_exception(err)
1067
- raise exc if exc
1068
- end
1069
-
1070
- # Convenient method to iterate over keys.
1071
- # If <i>pattern</i> is <tt>nil</tt>, all available keys are
1072
- # returned. If <i>secret_only</i> is <tt>true</tt>, the only
1073
- # secret keys are returned.
1074
- def each_key(pattern = nil, secret_only = false, &block) # :yields: key
1075
- keylist_start(pattern, secret_only)
1076
- begin
1077
- loop do
1078
- yield keylist_next
1079
- end
1080
- keys
1081
- rescue EOFError
1082
- # The last key in the list has already been returned.
1083
- ensure
1084
- keylist_end
1085
- end
1086
- end
1087
- alias each_keys each_key
1088
-
1089
- def keys(pattern = nil, secret_only = nil)
1090
- keys = Array.new
1091
- each_key(pattern, secret_only) do |key|
1092
- keys << key
1093
- end
1094
- keys
1095
- end
1096
-
1097
- # Get the key with the <i>fingerprint</i>.
1098
- # If <i>secret</i> is <tt>true</tt>, secret key is returned.
1099
- def get_key(fingerprint, secret = false)
1100
- rkey = Array.new
1101
- err = GPGME::gpgme_get_key(self, fingerprint, rkey, secret ? 1 : 0)
1102
- exc = GPGME::error_to_exception(err)
1103
- raise exc if exc
1104
- rkey[0]
1105
- end
1106
-
1107
- # Generate a new key pair.
1108
- # <i>parms</i> is a string which looks like
1109
- #
1110
- # <GnupgKeyParms format="internal">
1111
- # Key-Type: DSA
1112
- # Key-Length: 1024
1113
- # Subkey-Type: ELG-E
1114
- # Subkey-Length: 1024
1115
- # Name-Real: Joe Tester
1116
- # Name-Comment: with stupid passphrase
1117
- # Name-Email: joe@foo.bar
1118
- # Expire-Date: 0
1119
- # Passphrase: abc
1120
- # </GnupgKeyParms>
1121
- #
1122
- # If <i>pubkey</i> and <i>seckey</i> are both set to <tt>nil</tt>,
1123
- # it stores the generated key pair into your key ring.
1124
- def generate_key(parms, pubkey = Data.new, seckey = Data.new)
1125
- err = GPGME::gpgme_op_genkey(self, parms, pubkey, seckey)
1126
- exc = GPGME::error_to_exception(err)
1127
- raise exc if exc
1128
- end
1129
- alias genkey generate_key
1130
-
1131
- # Extract the public keys of the recipients.
1132
- def export_keys(recipients, keydata = Data.new)
1133
- err = GPGME::gpgme_op_export(self, recipients, 0, keydata)
1134
- exc = GPGME::error_to_exception(err)
1135
- raise exc if exc
1136
- keydata
1137
- end
1138
- alias export export_keys
1139
-
1140
- # Add the keys in the data buffer to the key ring.
1141
- def import_keys(keydata)
1142
- err = GPGME::gpgme_op_import(self, keydata)
1143
- exc = GPGME::error_to_exception(err)
1144
- raise exc if exc
1145
- end
1146
- alias import import_keys
1147
-
1148
- def import_result
1149
- GPGME::gpgme_op_import_result(self)
1150
- end
1151
-
1152
- # Delete the key from the key ring.
1153
- # If allow_secret is false, only public keys are deleted,
1154
- # otherwise secret keys are deleted as well.
1155
- def delete_key(key, allow_secret = false)
1156
- err = GPGME::gpgme_op_delete(self, key, allow_secret ? 1 : 0)
1157
- exc = GPGME::error_to_exception(err)
1158
- raise exc if exc
1159
- end
1160
- alias delete delete_key
1161
-
1162
- # Edit attributes of the key in the local key ring.
1163
- def edit_key(key, editfunc, hook_value = nil, out = Data.new)
1164
- err = GPGME::gpgme_op_edit(self, key, editfunc, hook_value, out)
1165
- exc = GPGME::error_to_exception(err)
1166
- raise exc if exc
1167
- end
1168
- alias edit edit_key
1169
-
1170
- # Edit attributes of the key on the card.
1171
- def edit_card_key(key, editfunc, hook_value = nil, out = Data.new)
1172
- err = GPGME::gpgme_op_card_edit(self, key, editfunc, hook_value, out)
1173
- exc = GPGME::error_to_exception(err)
1174
- raise exc if exc
1175
- end
1176
- alias edit_card edit_card_key
1177
- alias card_edit edit_card_key
1178
-
1179
- # Decrypt the ciphertext and return the plaintext.
1180
- def decrypt(cipher, plain = Data.new)
1181
- err = GPGME::gpgme_op_decrypt(self, cipher, plain)
1182
- exc = GPGME::error_to_exception(err)
1183
- raise exc if exc
1184
- plain
1185
- end
1186
-
1187
- def decrypt_verify(cipher, plain = Data.new)
1188
- err = GPGME::gpgme_op_decrypt_verify(self, cipher, plain)
1189
- exc = GPGME::error_to_exception(err)
1190
- raise exc if exc
1191
- plain
1192
- end
1193
-
1194
- def decrypt_result
1195
- GPGME::gpgme_op_decrypt_result(self)
1196
- end
1197
-
1198
- # Verify that the signature in the data object is a valid signature.
1199
- def verify(sig, signed_text = nil, plain = Data.new)
1200
- err = GPGME::gpgme_op_verify(self, sig, signed_text, plain)
1201
- exc = GPGME::error_to_exception(err)
1202
- raise exc if exc
1203
- plain
1204
- end
1205
-
1206
- def verify_result
1207
- GPGME::gpgme_op_verify_result(self)
1208
- end
1209
-
1210
- # Decrypt the ciphertext and return the plaintext.
1211
- def decrypt_verify(cipher, plain = Data.new)
1212
- err = GPGME::gpgme_op_decrypt_verify(self, cipher, plain)
1213
- exc = GPGME::error_to_exception(err)
1214
- raise exc if exc
1215
- plain
1216
- end
1217
-
1218
- # Remove the list of signers from this object.
1219
- def clear_signers
1220
- GPGME::gpgme_signers_clear(self)
1221
- end
1222
-
1223
- # Add _keys_ to the list of signers.
1224
- def add_signer(*keys)
1225
- keys.each do |key|
1226
- err = GPGME::gpgme_signers_add(self, key)
1227
- exc = GPGME::error_to_exception(err)
1228
- raise exc if exc
1229
- end
1230
- end
1231
-
1232
- # Create a signature for the text.
1233
- # <i>plain</i> is a data object which contains the text.
1234
- # <i>sig</i> is a data object where the generated signature is stored.
1235
- def sign(plain, sig = Data.new, mode = GPGME::SIG_MODE_NORMAL)
1236
- err = GPGME::gpgme_op_sign(self, plain, sig, mode)
1237
- exc = GPGME::error_to_exception(err)
1238
- raise exc if exc
1239
- sig
1240
- end
1241
-
1242
- def sign_result
1243
- GPGME::gpgme_op_sign_result(self)
1244
- end
1245
-
1246
- # Encrypt the plaintext in the data object for the recipients and
1247
- # return the ciphertext.
1248
- def encrypt(recp, plain, cipher = Data.new, flags = 0)
1249
- err = GPGME::gpgme_op_encrypt(self, recp, flags, plain, cipher)
1250
- exc = GPGME::error_to_exception(err)
1251
- raise exc if exc
1252
- cipher
1253
- end
1254
-
1255
- def encrypt_result
1256
- GPGME::gpgme_op_encrypt_result(self)
1257
- end
1258
-
1259
- def encrypt_sign(recp, plain, cipher = Data.new, flags = 0)
1260
- err = GPGME::gpgme_op_encrypt_sign(self, recp, flags, plain, cipher)
1261
- exc = GPGME::error_to_exception(err)
1262
- raise exc if exc
1263
- cipher
1264
- end
1265
- end
1266
-
1267
- # A public or secret key.
1268
- class Key
1269
- private_class_method :new
1270
-
1271
- attr_reader :keylist_mode, :protocol, :owner_trust
1272
- attr_reader :issuer_serial, :issuer_name, :chain_id
1273
- attr_reader :subkeys, :uids
1274
-
1275
- def trust
1276
- return :revoked if @revoked == 1
1277
- return :expired if @expired == 1
1278
- return :disabled if @disabled == 1
1279
- return :invalid if @invalid == 1
1280
- end
1281
-
1282
- def capability
1283
- caps = Array.new
1284
- caps << :encrypt if @can_encrypt
1285
- caps << :sign if @can_sign
1286
- caps << :certify if @can_certify
1287
- caps << :authenticate if @can_authenticate
1288
- caps
1289
- end
1290
-
1291
- def usable_for?(purposes)
1292
- unless purposes.kind_of? Array
1293
- purposes = [purposes]
1294
- end
1295
- return false if [:revoked, :expired, :disabled, :invalid].include? trust
1296
- return (purposes - capability).empty?
1297
- end
1298
-
1299
- def secret?
1300
- @secret == 1
1301
- end
1302
-
1303
- def inspect
1304
- primary_subkey = subkeys[0]
1305
- sprintf("#<#{self.class} %s %4d%c/%s %s trust=%s, owner_trust=%s, \
1306
- capability=%s, subkeys=%s, uids=%s>",
1307
- primary_subkey.secret? ? 'sec' : 'pub',
1308
- primary_subkey.length,
1309
- primary_subkey.pubkey_algo_letter,
1310
- primary_subkey.fingerprint[-8 .. -1],
1311
- primary_subkey.timestamp.strftime('%Y-%m-%d'),
1312
- trust.inspect,
1313
- VALIDITY_NAMES[@owner_trust].inspect,
1314
- capability.inspect,
1315
- subkeys.inspect,
1316
- uids.inspect)
1317
- end
1318
-
1319
- def to_s
1320
- primary_subkey = subkeys[0]
1321
- s = sprintf("%s %4d%c/%s %s\n",
1322
- primary_subkey.secret? ? 'sec' : 'pub',
1323
- primary_subkey.length,
1324
- primary_subkey.pubkey_algo_letter,
1325
- primary_subkey.fingerprint[-8 .. -1],
1326
- primary_subkey.timestamp.strftime('%Y-%m-%d'))
1327
- uids.each do |user_id|
1328
- s << "uid\t\t#{user_id.name} <#{user_id.email}>\n"
1329
- end
1330
- subkeys.each do |subkey|
1331
- s << subkey.to_s
1332
- end
1333
- s
1334
- end
1335
- end
1336
-
1337
- class SubKey
1338
- private_class_method :new
1339
-
1340
- attr_reader :pubkey_algo, :length, :keyid, :fpr
1341
- alias fingerprint fpr
1342
-
1343
- def trust
1344
- return :revoked if @revoked == 1
1345
- return :expired if @expired == 1
1346
- return :disabled if @disabled == 1
1347
- return :invalid if @invalid == 1
1348
- end
1349
-
1350
- def capability
1351
- caps = Array.new
1352
- caps << :encrypt if @can_encrypt
1353
- caps << :sign if @can_sign
1354
- caps << :certify if @can_certify
1355
- caps << :authenticate if @can_authenticate
1356
- caps
1357
- end
1358
-
1359
- def usable_for?(purposes)
1360
- unless purposes.kind_of? Array
1361
- purposes = [purposes]
88
+ Error.new(err)
1362
89
  end
1363
- return false if [:revoked, :expired, :disabled, :invalid].include? trust
1364
- return (purposes - capability).empty?
1365
- end
1366
-
1367
- def secret?
1368
- @secret == 1
1369
- end
1370
-
1371
- def timestamp
1372
- Time.at(@timestamp)
1373
- end
1374
-
1375
- def expires
1376
- Time.at(@expires)
1377
- end
1378
-
1379
- PUBKEY_ALGO_LETTERS = {
1380
- PK_RSA => ?R,
1381
- PK_ELG_E => ?g,
1382
- PK_ELG => ?G,
1383
- PK_DSA => ?D
1384
- }
1385
-
1386
- def pubkey_algo_letter
1387
- PUBKEY_ALGO_LETTERS[@pubkey_algo] || ??
1388
- end
1389
-
1390
- def inspect
1391
- sprintf("#<#{self.class} %s %4d%c/%s %s trust=%s, capability=%s>",
1392
- secret? ? 'ssc' : 'sub',
1393
- length,
1394
- pubkey_algo_letter,
1395
- (@fingerprint || @keyid)[-8 .. -1],
1396
- timestamp.strftime('%Y-%m-%d'),
1397
- trust.inspect,
1398
- capability.inspect)
1399
- end
1400
-
1401
- def to_s
1402
- sprintf("%s %4d%c/%s %s\n",
1403
- secret? ? 'ssc' : 'sub',
1404
- length,
1405
- pubkey_algo_letter,
1406
- (@fingerprint || @keyid)[-8 .. -1],
1407
- timestamp.strftime('%Y-%m-%d'))
1408
- end
1409
- end
1410
-
1411
- class UserID
1412
- private_class_method :new
1413
-
1414
- attr_reader :validity, :uid, :name, :comment, :email, :signatures
1415
-
1416
- def revoked?
1417
- @revoked == 1
1418
- end
1419
-
1420
- def invalid?
1421
- @invalid == 1
1422
- end
1423
-
1424
- def inspect
1425
- "#<#{self.class} #{name} <#{email}> \
1426
- validity=#{VALIDITY_NAMES[validity]}, signatures=#{signatures.inspect}>"
1427
- end
1428
- end
1429
-
1430
- class KeySig
1431
- private_class_method :new
1432
-
1433
- attr_reader :pubkey_algo, :keyid
1434
-
1435
- def revoked?
1436
- @revoked == 1
1437
- end
1438
-
1439
- def expired?
1440
- @expired == 1
1441
90
  end
1442
91
 
1443
- def invalid?
1444
- @invalid == 1
1445
- end
1446
-
1447
- def exportable?
1448
- @exportable == 1
1449
- end
1450
-
1451
- def timestamp
1452
- Time.at(@timestamp)
1453
- end
1454
-
1455
- def expires
1456
- Time.at(@expires)
1457
- end
1458
-
1459
- def inspect
1460
- "#<#{self.class} #{keyid} timestamp=#{timestamp}, expires=#{expires}>"
1461
- end
1462
- end
1463
-
1464
- class VerifyResult
1465
- private_class_method :new
1466
-
1467
- attr_reader :signatures
1468
- end
1469
-
1470
- class Signature
1471
- private_class_method :new
1472
-
1473
- attr_reader :summary, :fpr, :status, :notations, :wrong_key_usage
1474
- attr_reader :validity, :validity_reason
1475
- attr_reader :pka_trust, :pka_address
1476
- alias fingerprint fpr
1477
-
1478
- def timestamp
1479
- Time.at(@timestamp)
1480
- end
1481
-
1482
- def exp_timestamp
1483
- Time.at(@exp_timestamp)
1484
- end
1485
-
1486
- def to_s
1487
- ctx = Ctx.new
1488
- if from_key = ctx.get_key(fingerprint)
1489
- from = "#{from_key.subkeys[0].keyid} #{from_key.uids[0].uid}"
1490
- else
1491
- from = fingerprint
92
+ ##
93
+ # TODO find out what it does, can't seem to find a proper parameter that
94
+ # returns something other than nil.
95
+ def check_version(options = nil)
96
+ version = nil
97
+ if options.kind_of?(String)
98
+ version = options
99
+ elsif options.include?(:version)
100
+ version = options[:version]
1492
101
  end
1493
- case GPGME::gpgme_err_code(status)
1494
- when GPGME::GPG_ERR_NO_ERROR
1495
- "Good signature from #{from}"
1496
- when GPGME::GPG_ERR_SIG_EXPIRED
1497
- "Expired signature from #{from}"
1498
- when GPGME::GPG_ERR_KEY_EXPIRED
1499
- "Signature made from expired key #{from}"
1500
- when GPGME::GPG_ERR_CERT_REVOKED
1501
- "Signature made from revoked key #{from}"
1502
- when GPGME::GPG_ERR_BAD_SIGNATURE
1503
- "Bad signature from #{from}"
1504
- when GPGME::GPG_ERR_NO_ERROR
1505
- "No public key for #{from}"
102
+ unless GPGME::gpgme_check_version(version)
103
+ raise Error::InvalidVersion.new
1506
104
  end
1507
105
  end
1508
- end
1509
-
1510
- class DecryptResult
1511
- private_class_method :new
1512
-
1513
- attr_reader :unsupported_algorithm, :wrong_key_usage
1514
- end
1515
-
1516
- class SignResult
1517
- private_class_method :new
1518
-
1519
- attr_reader :invalid_signers, :signatures
1520
- end
1521
-
1522
- class EncryptResult
1523
- private_class_method :new
1524
-
1525
- attr_reader :invalid_recipients
1526
- end
1527
-
1528
- class InvalidKey
1529
- private_class_method :new
1530
-
1531
- attr_reader :fpr, :reason
1532
- alias fingerprint fpr
1533
- end
1534
-
1535
- class NewSignature
1536
- private_class_method :new
1537
-
1538
- attr_reader :type, :pubkey_algo, :hash_algo, :sig_class, :fpr
1539
- alias fingerprint fpr
1540
-
1541
- def timestamp
1542
- Time.at(@timestamp)
1543
- end
1544
- end
1545
-
1546
- class ImportStatus
1547
- private_class_method :new
1548
-
1549
- attr_reader :fpr, :result, :status
1550
- alias fingerprint fpr
1551
- end
1552
-
1553
- class ImportResult
1554
- private_class_method :new
1555
106
 
1556
- attr_reader :considered, :no_user_id, :imported, :imported_rsa, :unchanged
1557
- attr_reader :new_user_ids, :new_sub_keys, :new_signatures, :new_revocations
1558
- attr_reader :secret_read, :secret_imported, :secret_unchanged
1559
- attr_reader :not_imported, :imports
1560
107
  end
1561
108
  end