benburkert-gpgme 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,162 @@
1
+ = GPGME
2
+
3
+ This README is better is better viewed through the YARD formatted documentation:
4
+ http://rdoc.info/github/mrsimo/gpgme/master/frames for latest github version, or
5
+ http://rdoc.info/gems/gpgme for latest gem release.
6
+
7
+ == History behind this fork
8
+
9
+ This project started as my Ruby Mendicant University. The idea is to give an
10
+ overhaul to the API of this gem. As a relativelly new developer in the ruby
11
+ world, I found the documentation not very newbie friendly, and the API somewhat
12
+ different to the kind I'm used to in the ruby world.
13
+
14
+ GPG is a very powerful tool, and this gem is implemented using the C bindings,
15
+ making it very fast, and the only proper way to do it.
16
+
17
+ My objectives are as follows:
18
+
19
+ * Add test coverage of some type.
20
+ * Make documentation a little bit more newbie friendly.
21
+ * Improve the API to be more idiomatic.
22
+
23
+ == Requirements
24
+
25
+ * Ruby 1.8 or later
26
+ * GPGME 1.1.2 or later
27
+ * gpg-agent (optional, but recommended)
28
+
29
+ == Installation
30
+
31
+ $ gem install gpgme
32
+
33
+ == API
34
+
35
+ GPGME provides three levels of API. The highest level API is as simple as it
36
+ gets, the mid level API provides more functionality but might be less
37
+ user-friendly, and the lowest level API is close to the C interface of GPGME.
38
+
39
+ === The highest level API
40
+
41
+ For example, to create a cleartext signature of the plaintext from
42
+ stdin and write the result to stdout can be written as follows.
43
+
44
+ crypto = GPGME::Crypto.new
45
+ crypto.clearsign $stdin, :output => $stdout
46
+
47
+ === The mid level API
48
+
49
+ The same example can be rewritten in the mid level API as follows.
50
+
51
+ plain = GPGME::Data.new($stdin)
52
+ sig = GPGME::Data.new($stdout)
53
+ GPGME::Ctx.new do |ctx|
54
+ ctx.sign(plain, sig, GPGME::SIG_MODE_CLEAR)
55
+ end
56
+
57
+ === The lowest level API
58
+
59
+ The same example can be rewritten in the lowest level API as follows.
60
+
61
+ ret = []
62
+ GPGME::gpgme_new(ret)
63
+ ctx = ret.shift
64
+ GPGME::gpgme_data_new_from_fd(ret, 0)
65
+ plain = ret.shift
66
+ GPGME::gpgme_data_new_from_fd(ret, 1)
67
+ sig = ret.shift
68
+ GPGME::gpgme_op_sign(ctx, plain, sig, GPGME::SIG_MODE_CLEAR)
69
+
70
+ As you see, it's much harder to write a program in this API than the
71
+ highest level API. However, if you are already familiar with the C
72
+ interface of GPGME and want to control detailed behavior of GPGME, it
73
+ might be useful.
74
+
75
+ == Usage
76
+
77
+ All the high level methods attack the mid level {GPGME::Ctx} API. It is
78
+ recommended to read through the #{GPGME::Ctx.new} methods for common options.
79
+
80
+ Also, most of the input/output is done via {GPGME::Data} objects that create a
81
+ common interface for reading/writing to normal strings, or other common
82
+ objects like files. Read the {GPGME::Data} documentation to understand
83
+ how it works. Every time the lib needs a {GPGME::Data} object, it will be
84
+ automatically converted to it.
85
+
86
+ === Crypto
87
+
88
+ The {GPGME::Crypto} class has the high level convenience methods to encrypt,
89
+ decrypt, sign and verify signatures. Here are some examples, but it is
90
+ recommended to read through the {GPGME::Crypto} class to see all the options.
91
+
92
+ * Document encryption via {GPGME::Crypto#encrypt}:
93
+ crypto = GPGME::Crypto.new
94
+ crypto.encrypt "Hello world!", :recipients => "someone@example.com"
95
+
96
+ * Symmetric encryption:
97
+ crypto = GPGME::Crypto.new :password => "gpgme"
98
+ crypto.encrypt "Hello world!", :symmetric => true
99
+
100
+
101
+ * Document decryption via {GPGME::Crypto#decrypt} (including signature verification):
102
+ crypto.decrypt File.open("text.gpg")
103
+
104
+ * Document signing via {GPGME::Crypto#sign}. Also the clearsigning and detached signing.
105
+ crypto.sign "I hereby proclaim Github the beneficiary of all my money when I die"
106
+
107
+ * Sign verification via {GPGME::Crypto#verify}
108
+ sign = crypto.sign "Some text"
109
+ data = crypto.verify(sign) { |signature| signature.valid? }
110
+
111
+ === Key
112
+
113
+ The {GPGME::Key} object represents a key, and has the high level related
114
+ methods to work with them and find them, export, import, deletetion and
115
+ creation.
116
+
117
+ * Key listing
118
+ GPGME::Key.find(:secret, "someone@example.com")
119
+ # => Returns an array with all the secret keys available in the keychain.
120
+ # that match "someone@example.com"
121
+
122
+ * Key exporting
123
+ GPGME::Key.export("someone@example.com")
124
+ # => Returns a {GPGME::Data} object with the exported key.
125
+
126
+ key = GPGME::Key.find(:secret, "someone@example.com").first
127
+ key.export
128
+ # => Returns a {GPGME::Data} object with the exported key.
129
+
130
+ * Key importing
131
+ GPGME::Key.import(File.open("my.key"))
132
+
133
+ * TODO: Key generation
134
+
135
+ === Engine
136
+
137
+ Provides three convenience methods to obtain information about the gpg engine
138
+ one is currently using. For example:
139
+
140
+ * Getting current information
141
+ GPGME::Engine.engine_info.first
142
+ # => #<GPGME::EngineInfo:0x00000100d4fbd8
143
+ @file_name="/usr/local/bin/gpg",
144
+ @protocol=0,
145
+ @req_version="1.3.0",
146
+ @version="1.4.11">
147
+
148
+ * Changing home directory to work with different settings:
149
+ GPGME::Engine.home_dir = '/tmp'
150
+
151
+ == Contributing
152
+
153
+ To run the local test suite you need bundler and gpg:
154
+
155
+ bundle
156
+ rake compile # simple rake task to compile the extension
157
+ rake # runs the test suite
158
+
159
+ == License
160
+
161
+ The library itself is licensed under LGPLv2.1+. See the file
162
+ COPYING.LESSER and each file for copyright and warranty information.
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+ require 'rcov/rcovtask'
6
+ require 'yard'
7
+
8
+
9
+ desc "Re-compile the extensions"
10
+ task :compile do
11
+ FileUtils.rm_rf('tmp') if File.directory?('tmp')
12
+ mkdir 'tmp'
13
+
14
+ Dir.chdir('tmp') do
15
+ system "ruby #{File.dirname(__FILE__)}/ext/gpgme/extconf.rb"
16
+ system "make"
17
+ end
18
+ end
19
+
20
+ task :default => [:test]
21
+
22
+ Rake::TestTask.new(:test => :compile) do |t|
23
+ t.libs << 'test'
24
+ t.pattern = "test/**/*_test.rb"
25
+ t.verbose = true
26
+ end
27
+ Rake::Task['test'].comment = "Run all tests"
28
+
29
+ YARD::Rake::YardocTask.new
30
+
31
+ Rcov::RcovTask.new do |t|
32
+ t.libs << 'test'
33
+ t.pattern = "test/**/*_test.rb"
34
+ t.verbose = true
35
+ t.rcov_opts = ["-x gems"]
36
+ end
37
+
data/THANKS ADDED
@@ -0,0 +1,15 @@
1
+ Ruby-GPGME was originally written by Daiki Ueno. Other people
2
+ contributed by reporting problems, suggesting various improvements or
3
+ submitting actual code. Here is a list of those people. Help us keep
4
+ it complete and free of errors.
5
+
6
+
7
+
8
+ Carl Corliss
9
+ Jérémie Pierson
10
+ Kouhei Sutou
11
+ Kris Nuttycombe
12
+ Marc Dequènes
13
+ Rob Pitt
14
+ Rory McKinley
15
+ Sam Hall
@@ -0,0 +1,30 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'benburkert-gpgme'
3
+ s.version = '0.1.0'
4
+ s.authors = ['Daiki Ueno']
5
+ s.date = '2011-05-09'
6
+ s.email = 'ueno@unixuser.org'
7
+ s.extensions = ['ext/gpgme/extconf.rb']
8
+ s.files = `git ls-files`.split("\n")
9
+ s.has_rdoc = true
10
+ s.rubyforge_project = 'ruby-gpgme'
11
+ s.homepage = 'http://rubyforge.org/projects/ruby-gpgme/'
12
+ s.require_paths = ['lib', 'ext']
13
+ s.summary = "Ben Burkert's fork of the Ruby binding of GPGME."
14
+ s.description = %q{Ruby-GPGME is a Ruby language binding of GPGME (GnuPG
15
+ Made Easy). GnuPG Made Easy (GPGME) is a library designed to make access to
16
+ GnuPG easier for applications. It provides a High-Level Crypto API for
17
+ encryption, decryption, signing, signature verification and key management.}
18
+
19
+ s.add_development_dependency "mocha", "~> 0.9.12"
20
+ s.add_development_dependency "minitest", "~> 2.1.0"
21
+ s.add_development_dependency "yard", "~> 0.6.7"
22
+ s.add_development_dependency "rcov", "~> 0.9.9"
23
+
24
+ case RUBY_VERSION
25
+ when "1.9.2"
26
+ s.add_development_dependency "ruby-debug19" , "~> 0.11.6"
27
+ else
28
+ s.add_development_dependency "ruby-debug" , "~> 0.10.4"
29
+ end
30
+ end
data/examples/edit.rb ADDED
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gpgme'
3
+
4
+ # If you do not have gpg-agent installed, comment out the following
5
+ # and set it as :passphrase_callback.
6
+ #
7
+ # def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
8
+ # $stderr.write("Passphrase for #{uid_hint}: ")
9
+ # $stderr.flush
10
+ # begin
11
+ # system('stty -echo')
12
+ # io = IO.for_fd(fd, 'w')
13
+ # io.puts(gets)
14
+ # io.flush
15
+ # ensure
16
+ # (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
17
+ # system('stty echo')
18
+ # end
19
+ # $stderr.puts
20
+ # end
21
+
22
+ unless ENV['GPG_AGENT_INFO']
23
+ $stderr.puts("gpg-agent is not running. See the comment in #{$0}.")
24
+ exit(1)
25
+ end
26
+
27
+ unless ENV['GNUPGHOME']
28
+ $stderr.write('As GNUPGHOME is not set, the generated key pair will be stored into *your* keyring. Really proceed? (y/N) ')
29
+ $stderr.flush
30
+ exit(1) unless gets.chomp == 'y'
31
+ end
32
+
33
+ unless ARGV.length == 1
34
+ $stderr.puts("Usage: #{$0} KEYGRIP")
35
+ exit(1)
36
+ end
37
+
38
+ def progfunc(hook, what, type, current, total)
39
+ $stderr.write("#{what}: #{current}/#{total}\r")
40
+ $stderr.flush
41
+ end
42
+
43
+ def editfunc(hook, status, args, fd)
44
+ case status
45
+ when GPGME::GPGME_STATUS_GET_BOOL
46
+ begin
47
+ $stderr.write("#{args} (y/n) ")
48
+ $stderr.flush
49
+ line = gets
50
+ end until line =~ /\A\s*[ny]\s*\z/
51
+ io = IO.for_fd(fd)
52
+ io.puts(line.strip)
53
+ io.flush
54
+ when GPGME::GPGME_STATUS_GET_LINE, GPGME::GPGME_STATUS_GET_HIDDEN
55
+ $stderr.write("#{args}: ")
56
+ $stderr.flush
57
+ line = gets
58
+ io = IO.for_fd(fd)
59
+ io.puts(line)
60
+ io.flush
61
+ else
62
+ $stderr.puts([status, args].inspect)
63
+ end
64
+ end
65
+
66
+ ctx = GPGME::Ctx.new({:progress_callback => method(:progfunc),
67
+ # :passphrase_callback => method(:passfunc)
68
+ })
69
+ keystr = ARGV.shift
70
+ keys = ctx.keys(keystr)
71
+ if keys.empty?
72
+ $stderr.puts("Can't find key for \"#{keystr}\"")
73
+ exit(1)
74
+ end
75
+
76
+ $stderr.puts(keys.first.inspect)
77
+ ctx.edit_key(keys.first, method(:editfunc))
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gpgme'
3
+
4
+ # If you do not have gpg-agent installed, comment out the following
5
+ # and set it as :passphrase_callback.
6
+ #
7
+ # def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
8
+ # $stderr.write("Passphrase for #{uid_hint}: ")
9
+ # $stderr.flush
10
+ # begin
11
+ # system('stty -echo')
12
+ # io = IO.for_fd(fd, 'w')
13
+ # io.puts(gets)
14
+ # io.flush
15
+ # ensure
16
+ # (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
17
+ # system('stty echo')
18
+ # end
19
+ # $stderr.puts
20
+ # end
21
+
22
+ unless ENV['GPG_AGENT_INFO']
23
+ $stderr.puts("gpg-agent is not running. See the comment in #{$0}.")
24
+ exit(1)
25
+ end
26
+
27
+ unless ENV['GNUPGHOME']
28
+ $stderr.write('As GNUPGHOME is not set, the generated key pair will be stored into *your* keyring. Really proceed? (y/N) ')
29
+ $stderr.flush
30
+ exit(1) unless gets.chomp == 'y'
31
+ end
32
+
33
+ def progfunc(hook, what, type, current, total)
34
+ $stderr.write("#{what}: #{current}/#{total}\r")
35
+ $stderr.flush
36
+ end
37
+
38
+ ctx = GPGME::Ctx.new({:progress_callback => method(:progfunc),
39
+ # :passphrase_callback => method(:passfunc)
40
+ })
41
+
42
+ ctx.genkey(<<'EOF', nil, nil)
43
+ <GnupgKeyParms format="internal">
44
+ Key-Type: DSA
45
+ Key-Length: 1024
46
+ Subkey-Type: ELG-E
47
+ Subkey-Length: 1024
48
+ Name-Real: Joe Tester
49
+ Name-Comment: with stupid passphrase
50
+ Name-Email: joe@foo.bar
51
+ Expire-Date: 0
52
+ Passphrase: abc
53
+ </GnupgKeyParms>
54
+ EOF
55
+ $stderr.puts
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gpgme'
3
+
4
+ GPGME.list_keys(ARGV.shift) do |key|
5
+ puts(key)
6
+ end
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gpgme'
3
+
4
+ # If you do not have gpg-agent installed, comment out the following
5
+ # and set it as :passphrase_callback.
6
+ #
7
+ # def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
8
+ # $stderr.write("Passphrase for #{uid_hint}: ")
9
+ # $stderr.flush
10
+ # begin
11
+ # system('stty -echo')
12
+ # io = IO.for_fd(fd, 'w')
13
+ # io.puts(gets)
14
+ # io.flush
15
+ # ensure
16
+ # (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
17
+ # system('stty echo')
18
+ # end
19
+ # $stderr.puts
20
+ # end
21
+
22
+ unless ENV['GPG_AGENT_INFO']
23
+ $stderr.puts("gpg-agent is not running. See the comment in #{$0}.")
24
+ exit(1)
25
+ end
26
+
27
+ plain = 'test test test'
28
+ puts("Plaintext:\n#{plain}")
29
+
30
+ # Perform symmetric encryption on PLAIN.
31
+ cipher = GPGME::encrypt(nil, plain, {:armor => true,
32
+ # :passphrase_callback => method(:passfunc)
33
+ })
34
+ puts("Ciphertext:\n#{cipher}")
35
+
36
+ plain = GPGME::decrypt(cipher, {
37
+ # :passphrase_callback => method(:passfunc)
38
+ })
39
+ puts("Plaintext:\n#{plain}")
data/examples/sign.rb ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gpgme'
3
+
4
+ # If you do not have gpg-agent installed, comment out the following
5
+ # and set it as :passphrase_callback.
6
+ #
7
+ # def passfunc(hook, uid_hint, passphrase_info, prev_was_bad, fd)
8
+ # $stderr.write("Passphrase for #{uid_hint}: ")
9
+ # $stderr.flush
10
+ # begin
11
+ # system('stty -echo')
12
+ # io = IO.for_fd(fd, 'w')
13
+ # io.puts(gets)
14
+ # io.flush
15
+ # ensure
16
+ # (0 ... $_.length).each do |i| $_[i] = ?0 end if $_
17
+ # system('stty echo')
18
+ # end
19
+ # $stderr.puts
20
+ # end
21
+
22
+ unless ENV['GPG_AGENT_INFO']
23
+ $stderr.puts("gpg-agent is not running. See the comment in #{$0}.")
24
+ exit(1)
25
+ end
26
+
27
+ puts GPGME::clearsign('test test test', {
28
+ # :passphrase_callback => method(:passfunc)
29
+ })
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gpgme'
3
+
4
+ GPGME::verify(ARGF.read, nil, $stdout) do |signature|
5
+ puts(signature.to_s)
6
+ end
@@ -0,0 +1,26 @@
1
+ require 'mkmf'
2
+
3
+ unless find_executable('gpgme-config')
4
+ $stderr.puts("gpgme-config not found")
5
+ exit(1)
6
+ end
7
+
8
+ $CFLAGS += ' ' << `gpgme-config --cflags`.chomp
9
+ $libs += ' ' << `gpgme-config --libs`.chomp
10
+
11
+ checking_for('gpgme >= 1.1.3') do
12
+ if try_run(<<'End')
13
+ #include <gpgme.h>
14
+ #include <stdlib.h>
15
+ int main (void) {
16
+ return gpgme_check_version ("1.1.3") == NULL;
17
+ }
18
+ End
19
+ true
20
+ else
21
+ $CFLAGS += ' -DRUBY_GPGME_NEED_WORKAROUND_KEYLIST_NEXT'
22
+ false
23
+ end
24
+ end
25
+ have_func('gpgme_op_export_keys')
26
+ create_makefile ('gpgme_n')