bendiken-openpgp 0.0.1.1 → 0.0.1.2

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.
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