openpgp 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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|