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 +12 -0
- data/Rakefile +14 -0
- data/VERSION +1 -1
- data/lib/openpgp.rb +9 -5
- data/lib/openpgp/armor.rb +1 -39
- data/lib/openpgp/message.rb +0 -1
- data/lib/openpgp/packet.rb +82 -2
- data/lib/openpgp/util.rb +44 -0
- metadata +3 -2
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
|
+
0.0.1.2
|
data/lib/openpgp.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
require 'openpgp/version'
|
2
|
-
require 'openpgp/
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
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([
|
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
|
data/lib/openpgp/message.rb
CHANGED
data/lib/openpgp/packet.rb
CHANGED
@@ -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
|
-
|
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
|
##
|
data/lib/openpgp/util.rb
ADDED
@@ -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.
|
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-
|
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
|