openpgp 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,6 +14,9 @@ module OpenPGP
14
14
 
15
15
  DEFAULT = SHA1
16
16
 
17
+ ##
18
+ # @param [Symbol, String, Integer] identifier
19
+ # @return [Class]
17
20
  def self.for(identifier)
18
21
  case identifier
19
22
  when Symbol then const_get(identifier.to_s.upcase)
@@ -28,30 +31,46 @@ module OpenPGP
28
31
  end
29
32
  end
30
33
 
34
+ ##
35
+ # @return [Integer]
31
36
  def self.to_i() identifier end
32
37
 
38
+ ##
39
+ # @return [Integer]
33
40
  def self.identifier
34
41
  const_get(:IDENTIFIER)
35
42
  end
36
43
 
44
+ ##
45
+ # @return [Symbol]
37
46
  def self.algorithm
38
47
  name.split('::').last.to_sym unless self == Digest
39
48
  end
40
49
 
50
+ ##
51
+ # @return [Integer]
41
52
  def self.hexsize
42
53
  size * 2
43
54
  end
44
55
 
56
+ ##
57
+ # @return [Integer]
45
58
  def self.size
46
59
  require 'digest' unless defined?(::Digest)
47
60
  ::Digest.const_get(algorithm).new.digest_length
48
61
  end
49
62
 
63
+ ##
64
+ # @param [String] data
65
+ # @return [String]
50
66
  def self.hexdigest(data)
51
67
  require 'digest' unless defined?(::Digest)
52
68
  ::Digest.const_get(algorithm).hexdigest(data).upcase
53
69
  end
54
70
 
71
+ ##
72
+ # @param [String] data
73
+ # @return [String]
55
74
  def self.digest(data)
56
75
  require 'digest' unless defined?(::Digest)
57
76
  ::Digest.const_get(algorithm).digest(data)
@@ -1,5 +1,6 @@
1
1
  module OpenPGP
2
2
  class Digest
3
+ ##
3
4
  class MD5 < Digest
4
5
  IDENTIFIER = 1
5
6
  end
@@ -1,5 +1,6 @@
1
1
  module OpenPGP
2
2
  class Digest
3
+ ##
3
4
  class RIPEMD160 < Digest
4
5
  IDENTIFIER = 3
5
6
  end
@@ -1,5 +1,6 @@
1
1
  module OpenPGP
2
2
  class Digest
3
+ ##
3
4
  class SHA1 < Digest
4
5
  IDENTIFIER = 2
5
6
  end
@@ -1,17 +1,21 @@
1
1
  module OpenPGP
2
2
  class Digest
3
+ ##
3
4
  class SHA224 < Digest
4
5
  IDENTIFIER = 11
5
6
  end
6
7
 
8
+ ##
7
9
  class SHA256 < Digest
8
10
  IDENTIFIER = 8
9
11
  end
10
12
 
13
+ ##
11
14
  class SHA384 < Digest
12
15
  IDENTIFIER = 9
13
16
  end
14
17
 
18
+ ##
15
19
  class SHA512 < Digest
16
20
  IDENTIFIER = 10
17
21
  end
@@ -1,8 +1,11 @@
1
1
  module OpenPGP
2
+ ##
2
3
  class Engine
3
4
  autoload :GnuPG, 'openpgp/engine/gnupg'
4
5
  autoload :OpenSSL, 'openpgp/engine/openssl'
5
6
 
7
+ ##
8
+ # @return [Boolean]
6
9
  def self.available?
7
10
  begin
8
11
  load!(true)
@@ -12,14 +15,25 @@ module OpenPGP
12
15
  end
13
16
  end
14
17
 
18
+ ##
19
+ # @param [Boolean] reload
20
+ # @return [void]
21
+ # @raise [LoadError]
15
22
  def self.load!(reload = false)
16
23
  raise LoadError
17
24
  end
18
25
 
26
+ ##
27
+ # @return [void]
28
+ # @raise [LoadError]
19
29
  def self.install!
20
30
  load!
21
31
  end
22
32
 
33
+ ##
34
+ # @yield [engine]
35
+ # @yieldparam [Engine] engine
36
+ # @return [void]
23
37
  def self.use(&block)
24
38
  load!
25
39
  block.call(self)
@@ -27,6 +41,9 @@ module OpenPGP
27
41
 
28
42
  protected
29
43
 
44
+ ##
45
+ # @param [Module] extension
46
+ # @return [void]
30
47
  def self.install_extensions!(extension)
31
48
  name = extension.name.split('::').last.to_sym
32
49
 
@@ -6,6 +6,8 @@ module OpenPGP class Engine
6
6
  class GnuPG < Engine
7
7
  class Error < IOError; end
8
8
 
9
+ ##
10
+ # @return [Boolean]
9
11
  def self.available?
10
12
  self.new.available?
11
13
  end
@@ -19,9 +21,14 @@ module OpenPGP class Engine
19
21
  :no_random_seed_file => true,
20
22
  }
21
23
 
24
+ # @return [String]
22
25
  attr_accessor :where
26
+
27
+ # @return [Hash{Symbol => Object}]
23
28
  attr_accessor :options
24
29
 
30
+ ##
31
+ # @param [Hash{Symbol => Object}] options
25
32
  def initialize(options = {})
26
33
  @where = '/usr/bin/env gpg' # FIXME
27
34
  @options = OPTIONS.merge!(options)
@@ -29,18 +36,25 @@ module OpenPGP class Engine
29
36
 
30
37
  ##
31
38
  # Determines if GnuPG is available.
39
+ #
40
+ # @return [Boolean]
32
41
  def available?
33
42
  !!version
34
43
  end
35
44
 
36
45
  ##
37
46
  # Returns the GnuPG version number.
47
+ #
48
+ # @return [String]
38
49
  def version
39
50
  exec(:version).readline =~ /^gpg \(GnuPG\) (.*)$/ ? $1 : nil
40
51
  end
41
52
 
42
53
  ##
43
54
  # Generates a new OpenPGP keypair and stores it GnuPG's keyring.
55
+ #
56
+ # @param [Hash{Symbol => String}] info
57
+ # @return [Integer]
44
58
  def gen_key(info = {})
45
59
  stdin, stdout, stderr = exec3(:gen_key) do |stdin, stdout, stderr|
46
60
  stdin.puts "Key-Type: #{info[:key_type]}" if info[:key_type]
@@ -64,22 +78,34 @@ module OpenPGP class Engine
64
78
 
65
79
  ##
66
80
  # Exports a specified key from the GnuPG keyring.
81
+ #
82
+ # @param [String] key_id
83
+ # @param [Hash{Symbol => Object}] options
84
+ # @return [Message]
67
85
  def export(key_id = nil, opts = {})
68
86
  OpenPGP::Message.parse(exec([:export, *[key_id].flatten], opts ).read)
69
87
  end
70
88
 
71
- ##
72
89
  ##
73
90
  # Imports a specified keyfile into the GnuPG keyring.
91
+ #
92
+ # @return [void]
74
93
  def import()
75
94
  # TODO
76
95
  end
77
96
 
97
+ ##
98
+ # @param [String] key_id
99
+ # @return [void]
78
100
  def delete_secret_and_public_key(key_id)
79
101
  opts = {:batch => true}
80
102
  OpenPGP::Message.parse(exec([:delete_secret_and_public_key, key_fingerprint(key_id)], opts ).read)
81
103
  end
82
104
 
105
+ ##
106
+ # @param [String] key_id
107
+ # @param [Hash{Symbol => Object}] options
108
+ # @return [String]
83
109
  def key_fingerprint(key_id, opts = {})
84
110
  message = exec([:fingerprint, *[key_id].flatten], opts ).read
85
111
  if message =~ /Key fingerprint = (.*)\n/
@@ -90,24 +116,36 @@ module OpenPGP class Engine
90
116
 
91
117
  ##
92
118
  # Returns an array of key IDs/titles of the keys in the public keyring.
119
+ #
120
+ # @return [Array]
93
121
  def list_keys()
94
122
  # TODO
95
123
  end
96
124
 
97
125
  ##
98
126
  # Encrypts the given plaintext to the specified recipients.
127
+ #
128
+ # @param [String] plaintext
129
+ # @param [Hash{Symbol => Object}] options
130
+ # @return [String]
99
131
  def encrypt(plaintext, options = {})
100
132
  # TODO
101
133
  end
102
134
 
103
135
  ##
104
136
  # Decrypts the given ciphertext using the specified key ID.
137
+ #
138
+ # @param [String] ciphertext
139
+ # @param [Hash{Symbol => Object}] options
140
+ # @return [String]
105
141
  def decrypt(ciphertext, options = {})
106
142
  # TODO
107
143
  end
108
144
 
109
145
  ##
110
146
  # Makes an OpenPGP signature.
147
+ #
148
+ # @return [void]
111
149
  def sign()
112
150
  # TODO
113
151
  end
@@ -139,6 +177,10 @@ module OpenPGP class Engine
139
177
  ##
140
178
  # Executes a GnuPG command, yielding the standard input and returning
141
179
  # the standard output.
180
+ #
181
+ # @param [String] command
182
+ # @param [Hash{Symbol => Object}] options
183
+ # @return [IO]
142
184
  def exec(command, options = {}, &block) #:yields: stdin
143
185
  exec4(command, options) do |pid, stdin, stdout, stderr|
144
186
  block.call(stdin) if block_given?
@@ -152,6 +194,10 @@ module OpenPGP class Engine
152
194
  ##
153
195
  # Executes a GnuPG command, yielding and returning the standard input,
154
196
  # output and error.
197
+ #
198
+ # @param [String] command
199
+ # @param [Hash{Symbol => Object}] options
200
+ # @return [Array(IO, IO, IO)]
155
201
  def exec3(command, options = {}, &block) #:yields: stdin, stdout, stderr
156
202
  exec4(command, options) do |pid, stdin, stdout, stderr|
157
203
  block.call(stdin, stdout, stderr) if block_given?
@@ -165,6 +211,10 @@ module OpenPGP class Engine
165
211
  ##
166
212
  # Executes a GnuPG command, yielding the process identifier as well as
167
213
  # the standard input, output and error.
214
+ #
215
+ # @param [String] command
216
+ # @param [Hash{Symbol => Object}] options
217
+ # @return [void]
168
218
  def exec4(command, options = {}, &block) #:yields: pid, stdin, stdout, stderr
169
219
  require 'rubygems'
170
220
  require 'open4'
@@ -175,6 +225,10 @@ module OpenPGP class Engine
175
225
 
176
226
  ##
177
227
  # Constructs the GnuPG command-line for use with +exec+.
228
+ #
229
+ # @param [String] command
230
+ # @param [Hash{Symbol => Object}] options
231
+ # @return [String]
178
232
  def cmdline(command, options = {})
179
233
  command = [command].flatten
180
234
  cmdline = [where]
@@ -186,6 +240,9 @@ module OpenPGP class Engine
186
240
 
187
241
  ##
188
242
  # Translates Ruby symbols into GnuPG option arguments.
243
+ #
244
+ # @param [String, #to_s] option
245
+ # @return [String]
189
246
  def option(option)
190
247
  "--" << option.to_s.gsub('_', '-')
191
248
  end
@@ -1,15 +1,24 @@
1
1
  module OpenPGP
2
2
  class Engine
3
3
  class OpenSSL < Engine
4
+ ##
5
+ # @param [Boolean] reload
6
+ # @return [void]
7
+ # @raise [LoadError]
4
8
  def self.load!(reload = false)
5
9
  require 'openssl' unless defined?(::OpenSSL) || reload
6
10
  end
7
11
 
12
+ ##
13
+ # @return [void]
14
+ # @raise [LoadError]
8
15
  def self.install!
9
16
  load!
10
17
  [Random, Digest].each { |mod| install_extensions! mod }
11
18
  end
12
19
 
20
+ ##
21
+ # @private
13
22
  module Random #:nodoc:
14
23
  def number(bits = 32, options = {})
15
24
  ::OpenSSL::BN.rand(bits)
@@ -24,6 +33,8 @@ module OpenPGP
24
33
  end
25
34
  end
26
35
 
36
+ ##
37
+ # @private
27
38
  module Digest #:nodoc:
28
39
  def size
29
40
  ::OpenSSL::Digest.new(algorithm.to_s).digest_length
@@ -38,10 +49,11 @@ module OpenPGP
38
49
  end
39
50
  end
40
51
 
52
+ ##
53
+ # @private
41
54
  module Cipher #:nodoc:
42
55
  # TODO
43
56
  end
44
-
45
57
  end
46
58
  end
47
59
  end
@@ -8,10 +8,15 @@ module OpenPGP
8
8
  class Message
9
9
  include Enumerable
10
10
 
11
+ # @return [Array<Packet>]
11
12
  attr_accessor :packets
12
13
 
13
14
  ##
14
15
  # Creates an encrypted OpenPGP message.
16
+ #
17
+ # @param [Object] data
18
+ # @param [Hash{Symbol => Object}] options
19
+ # @return [Message]
15
20
  def self.encrypt(data, options = {}, &block)
16
21
  if options[:symmetric]
17
22
  key = (options[:key] || S2K::DEFAULT.new(options[:passphrase]))
@@ -38,6 +43,9 @@ module OpenPGP
38
43
  end
39
44
 
40
45
  ##
46
+ # @param [Object] data
47
+ # @param [Hash{Symbol => Object}] options
48
+ # @return [Object]
41
49
  def self.decrypt(data, options = {}, &block)
42
50
  raise NotImplementedError # TODO
43
51
  end
@@ -45,8 +53,10 @@ module OpenPGP
45
53
  ##
46
54
  # Parses an OpenPGP message.
47
55
  #
48
- # @see http://tools.ietf.org/html/rfc4880#section-4.1
49
- # @see http://tools.ietf.org/html/rfc4880#section-4.2
56
+ # @param [Buffer, #to_str] data
57
+ # @return [Message]
58
+ # @see http://tools.ietf.org/html/rfc4880#section-4.1
59
+ # @see http://tools.ietf.org/html/rfc4880#section-4.2
50
60
  def self.parse(data)
51
61
  data = Buffer.new(data.to_str) if data.respond_to?(:to_str)
52
62
 
@@ -61,36 +71,56 @@ module OpenPGP
61
71
  msg
62
72
  end
63
73
 
74
+ ##
75
+ # @return [IO, #write] io
76
+ # @return [void]
64
77
  def self.write(io = nil, &block)
65
78
  data = self.new(&block).to_s
66
79
  io.respond_to?(:write) ? io.write(data) : data
67
80
  end
68
81
 
82
+ ##
83
+ # @param [Array<Packet>] packets
69
84
  def initialize(*packets, &block)
70
85
  @packets = packets.flatten
71
86
  block.call(self) if block_given?
72
87
  end
73
88
 
89
+ ##
90
+ # @yield [packet]
91
+ # @yieldparam [Packet] packet
92
+ # @return [Enumerator]
74
93
  def each(&block) # :yields: packet
75
94
  packets.each(&block)
76
95
  end
77
96
 
97
+ ##
98
+ # @return [Array<Packet>]
78
99
  def to_a
79
100
  packets.to_a
80
101
  end
81
102
 
103
+ ##
104
+ # @param [Packet] packet
105
+ # @return [self]
82
106
  def <<(packet)
83
107
  packets << packet
84
108
  end
85
109
 
110
+ ##
111
+ # @return [Boolean]
86
112
  def empty?
87
113
  packets.empty?
88
114
  end
89
115
 
116
+ ##
117
+ # @return [Integer]
90
118
  def size
91
119
  inject(0) { |sum, packet| sum + packet.size }
92
120
  end
93
121
 
122
+ ##
123
+ # @return [String]
94
124
  def to_s
95
125
  Buffer.write do |buffer|
96
126
  packets.each do |packet|