bendiken-openpgp 0.0.1.1 → 0.0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  This is a pure-Ruby implementation of the OpenPGP Message Format (RFC 4880).
4
4
 
5
+ * http://openpgp.rubyforge.org
6
+ * http://github.com/bendiken/openpgp
7
+
5
8
 
6
9
  === About OpenPGP
7
10
 
@@ -81,6 +84,15 @@ directly from GitHub as follows:
81
84
  % [sudo] gem install bendiken-openpgp -s http://gems.github.com
82
85
 
83
86
 
87
+ == Resources
88
+
89
+ * http://openpgp.rubyforge.org
90
+ * http://github.com/bendiken/openpgp
91
+ * http://rubyforge.org/projects/openpgp
92
+ * http://raa.ruby-lang.org/project/openpgp
93
+ * http://www.ohloh.net/p/openpgp
94
+
95
+
84
96
  == Authors
85
97
 
86
98
  * Arto Bendiken (mailto:arto.bendiken@gmail.com) - http://ar.to
data/Rakefile CHANGED
@@ -3,3 +3,17 @@ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'lib')))
3
3
  require 'rubygems'
4
4
  require 'rakefile' # http://github.com/bendiken/rakefile
5
5
  require 'openpgp'
6
+
7
+ desc "Generate YARD documentation (with title)"
8
+ task :yardocs => :yardoc do
9
+ # FIXME: fork YARD and patch it to allow the title to be configured
10
+ sh "sed -i 's/YARD Documentation/OpenPGP.rb Documentation/' doc/yard/index.html"
11
+
12
+ # TODO: investigate why YARD doesn't auto-link URLs like RDoc does
13
+ html = File.read(file = 'doc/yard/readme.html')
14
+ html.gsub!(/>(http:\/\/)([\w\d\.\/\-]+)/, '><a href="\1\2" target="_blank">\2</a>')
15
+ html.gsub!(/(http:\/\/ar\.to\/[\w\d\.\/]+)/, '<a href="\1">\1</a>')
16
+ html.gsub!(/(http:\/\/ar\.to)([^\/]+)/, '<a href="\1" target="_top">ar.to</a>\2')
17
+ html.gsub!(/(mailto:[^\)]+)/, '<a href="\1">\1</a>')
18
+ File.open(file, 'wb') { |f| f.puts html }
19
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1.1
1
+ 0.0.1.2
data/lib/openpgp.rb CHANGED
@@ -1,6 +1,10 @@
1
1
  require 'openpgp/version'
2
- require 'openpgp/armor'
3
- require 'openpgp/message'
4
- require 'openpgp/packet'
5
- require 'openpgp/algorithm'
6
- require 'openpgp/gnupg'
2
+ require 'openpgp/util'
3
+
4
+ module OpenPGP
5
+ autoload :Armor, 'openpgp/armor'
6
+ autoload :Message, 'openpgp/message'
7
+ autoload :Packet, 'openpgp/packet'
8
+ autoload :Algorithm, 'openpgp/algorithm'
9
+ autoload :GnuPG, 'openpgp/gnupg'
10
+ end
data/lib/openpgp/armor.rb CHANGED
@@ -1,16 +1,4 @@
1
1
  module OpenPGP
2
- ##
3
- # Alias for OpenPGP::Armor.encode().
4
- def self.enarmor(data, marker = 'MESSAGE', headers = {})
5
- Armor.encode(data, marker, headers)
6
- end
7
-
8
- ##
9
- # Alias for OpenPGP::Armor.decode().
10
- def self.dearmor(text, marker = nil)
11
- Armor.decode(text, marker)
12
- end
13
-
14
2
  ##
15
3
  # OpenPGP ASCII Armor utilities.
16
4
  #
@@ -42,14 +30,11 @@ module OpenPGP
42
30
  # @see http://tools.ietf.org/html/rfc4880#section-6.2
43
31
  # @see http://tools.ietf.org/html/rfc2045
44
32
  def self.encode(data, marker = 'MESSAGE', headers = {})
45
- require 'stringio'
46
- require 'base64'
47
-
48
33
  text = StringIO.new
49
34
  text << self.header(marker) << "\n"
50
35
  headers.each { |key, value| text << "#{key}: #{value}\n" }
51
36
  text << "\n" << Base64.encode64(data)
52
- text << "=" << Base64.encode64([self.crc24(data)].pack('N')[1, 3])
37
+ text << "=" << Base64.encode64([OpenPGP.crc24(data)].pack('N')[1, 3])
53
38
  text << self.footer(marker) << "\n"
54
39
  text.string
55
40
  end
@@ -58,9 +43,6 @@ module OpenPGP
58
43
  # @see http://tools.ietf.org/html/rfc4880#section-6
59
44
  # @see http://tools.ietf.org/html/rfc2045
60
45
  def self.decode(text, marker = nil)
61
- require 'stringio'
62
- require 'base64'
63
-
64
46
  data, crc, state = StringIO.new, nil, :begin
65
47
  text.each_line do |line|
66
48
  line.chomp!
@@ -88,26 +70,6 @@ module OpenPGP
88
70
  end
89
71
  data.string
90
72
  end
91
-
92
- ##
93
- # @see http://tools.ietf.org/html/rfc4880#section-6.1
94
- CRC24_INIT = 0x00b704ce
95
- CRC24_POLY = 0x01864cfb
96
-
97
- ##
98
- # @see http://tools.ietf.org/html/rfc4880#section-6
99
- # @see http://tools.ietf.org/html/rfc4880#section-6.1
100
- def self.crc24(data)
101
- crc = CRC24_INIT
102
- data.each_byte do |octet|
103
- crc ^= octet << 16
104
- 8.times do
105
- crc <<= 1
106
- crc ^= CRC24_POLY if (crc & 0x01000000).nonzero?
107
- end
108
- end
109
- crc &= 0x00ffffff
110
- end
111
73
  end
112
74
 
113
75
  include Armor::Markers
@@ -14,7 +14,6 @@ module OpenPGP
14
14
  # @see http://tools.ietf.org/html/rfc4880#section-4.1
15
15
  # @see http://tools.ietf.org/html/rfc4880#section-4.2
16
16
  def self.parse(data)
17
- require 'stringio'
18
17
  data = StringIO.new(data.to_str) if data.respond_to?(:to_str)
19
18
 
20
19
  msg = self.new
@@ -14,7 +14,6 @@ module OpenPGP
14
14
  #
15
15
  # @see http://tools.ietf.org/html/rfc4880#section-4.2
16
16
  def self.parse(data)
17
- require 'stringio'
18
17
  data = StringIO.new(data.to_str) if data.respond_to?(:to_str)
19
18
 
20
19
  unless data.eof?
@@ -78,6 +77,32 @@ module OpenPGP
78
77
  @tag, @data, @size = tag, data, data ? data.size : 0
79
78
  end
80
79
 
80
+ ##
81
+ # @see http://tools.ietf.org/html/rfc4880#section-3.5
82
+ def read_timestamp
83
+ read_unpacked(4, 'N')
84
+ end
85
+
86
+ ##
87
+ # @see http://tools.ietf.org/html/rfc4880#section-3.2
88
+ def read_mpi
89
+ length = read_unpacked(2, 'n') # length in bits
90
+ length = ((length + 7) / 8.0).floor # length in bytes
91
+ read_bytes(length)
92
+ end
93
+
94
+ def read_unpacked(count, format)
95
+ read_bytes(count).unpack(format).first
96
+ end
97
+
98
+ def read_byte
99
+ data.getc
100
+ end
101
+
102
+ def read_bytes(count)
103
+ data.read(count)
104
+ end
105
+
81
106
  ##
82
107
  # OpenPGP Public-Key Encrypted Session Key packet (tag 1).
83
108
  #
@@ -118,7 +143,62 @@ module OpenPGP
118
143
  # @see http://tools.ietf.org/html/rfc4880#section-11.1
119
144
  # @see http://tools.ietf.org/html/rfc4880#section-12
120
145
  class PublicKey < Packet
121
- # TODO
146
+ attr_accessor :version, :timestamp, :algorithm
147
+ attr_accessor :key, :key_fields
148
+
149
+ def initialize(tag = nil, data = nil)
150
+ super
151
+ @data = StringIO.new(@data.to_str)
152
+ @key = {}
153
+
154
+ case @version = @data.getc
155
+ when 2, 3
156
+ # TODO
157
+ when 4
158
+ @timestamp, @algorithm = read_timestamp, read_byte
159
+ read_key_material
160
+ end
161
+ end
162
+
163
+ ##
164
+ # @see http://tools.ietf.org/html/rfc4880#section-5.5.2
165
+ def read_key_material
166
+ @key_fields = case algorithm
167
+ when Algorithm::Asymmetric::RSA
168
+ [:n, :e]
169
+ when Algorithm::Asymmetric::ELG_E
170
+ [:p, :g, :y]
171
+ when Algorithm::Asymmetric::DSA
172
+ [:p, :q, :g, :y]
173
+ else
174
+ raise "Unknown OpenPGP key algorithm: #{algorithm}"
175
+ end
176
+ @key_fields.each { |field| key[field] = read_mpi }
177
+ key_id
178
+ end
179
+
180
+ def key_id
181
+ @key_id ||= fingerprint[-8..-1]
182
+ end
183
+
184
+ ##
185
+ # @see http://tools.ietf.org/html/rfc4880#section-12.2
186
+ # @see http://tools.ietf.org/html/rfc4880#section-3.3
187
+ def fingerprint
188
+ @fingerprint ||= case version
189
+ when 2, 3
190
+ require 'digest/md5'
191
+ Digest::MD5.hexdigest([key[:n], key[:e]].join)
192
+ when 4
193
+ require 'digest/sha1'
194
+ material = [0x99.chr, [size].pack('n'), version.chr, [timestamp].pack('N'), algorithm.chr]
195
+ @key_fields.each do |key_field|
196
+ material << [OpenPGP.bitlength(key[key_field])].pack('n')
197
+ material << key[key_field]
198
+ end
199
+ Digest::SHA1.hexdigest(material.join)
200
+ end
201
+ end
122
202
  end
123
203
 
124
204
  ##
@@ -0,0 +1,44 @@
1
+ require 'stringio'
2
+ require 'base64'
3
+
4
+ module OpenPGP
5
+ ##
6
+ # Alias for OpenPGP::Armor.encode().
7
+ def self.enarmor(data, marker = 'MESSAGE', headers = {})
8
+ Armor.encode(data, marker, headers)
9
+ end
10
+
11
+ ##
12
+ # Alias for OpenPGP::Armor.decode().
13
+ def self.dearmor(text, marker = nil)
14
+ Armor.decode(text, marker)
15
+ end
16
+
17
+ ##
18
+ # @see http://tools.ietf.org/html/rfc4880#section-6.1
19
+ CRC24_INIT = 0x00b704ce
20
+ CRC24_POLY = 0x01864cfb
21
+
22
+ ##
23
+ # @see http://tools.ietf.org/html/rfc4880#section-6
24
+ # @see http://tools.ietf.org/html/rfc4880#section-6.1
25
+ def self.crc24(data)
26
+ crc = CRC24_INIT
27
+ data.each_byte do |octet|
28
+ crc ^= octet << 16
29
+ 8.times do
30
+ crc <<= 1
31
+ crc ^= CRC24_POLY if (crc & 0x01000000).nonzero?
32
+ end
33
+ end
34
+ crc &= 0x00ffffff
35
+ end
36
+
37
+ ##
38
+ # Returns the bit length of a multiprecision integer (MPI).
39
+ #
40
+ # @see http://tools.ietf.org/html/rfc4880#section-3.2
41
+ def self.bitlength(data)
42
+ (data.size - 1) * 8 + (Math.log(data[0]) / Math.log(2)).floor + 1
43
+ end
44
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bendiken-openpgp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.1
4
+ version: 0.0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arto Bendiken
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-18 00:00:00 -07:00
12
+ date: 2009-04-30 00:00:00 -07:00
13
13
  default_executable: openpgp
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -42,6 +42,7 @@ files:
42
42
  - lib/openpgp/gnupg.rb
43
43
  - lib/openpgp/message.rb
44
44
  - lib/openpgp/packet.rb
45
+ - lib/openpgp/util.rb
45
46
  - lib/openpgp/version.rb
46
47
  has_rdoc: false
47
48
  homepage: http://github.com/bendiken/openpgp