klacointe-openpgp 0.0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,186 @@
1
+ module OpenPGP
2
+ ##
3
+ # OpenPGP string-to-key (S2K) specifiers.
4
+ #
5
+ # @see http://tools.ietf.org/html/rfc4880#section-3.7
6
+ class S2K
7
+ attr_accessor :passphrase
8
+ attr_accessor :algorithm
9
+
10
+ def self.parse(input)
11
+ case mode = input.read_byte
12
+ when 0 then S2K::Simple.parse(input) # Simple S2K
13
+ when 1 then S2K::Salted.parse(input) # Salted S2K
14
+ when 3 then S2K::Iterated.parse(input) # Iterated and Salted S2K
15
+ when 100..110 then S2K.new(:data => input.read) # Private/Experimental S2K
16
+ else # TODO
17
+ end
18
+ end
19
+
20
+ def self.identifier
21
+ const_get(:IDENTIFIER)
22
+ end
23
+
24
+ def initialize(passphrase = nil, options = {}, &block)
25
+ @passphrase = passphrase.to_s
26
+ options.each { |k, v| instance_variable_set("@#{k}", v) }
27
+
28
+ block.call(self) if block_given?
29
+ end
30
+
31
+ def write(buffer)
32
+ buffer.write_byte(identifier)
33
+ buffer.write_byte(digest.to_i)
34
+ end
35
+
36
+ def identifier
37
+ @identifier || self.class.identifier
38
+ end
39
+
40
+ def to_hash
41
+ {:mode => identifier, :algorithm => digest.to_i}
42
+ end
43
+
44
+ def to_s
45
+ Buffer.write { |buffer| write(buffer) }
46
+ end
47
+
48
+ def to_key(key_size = 16)
49
+ key = if digest.size >= key_size
50
+ digest.digest(digest_input)
51
+ else
52
+ Buffer.write do |buffer|
53
+ (key_size / digest.size.to_f).ceil.times do |i|
54
+ buffer << digest.digest(digest_input_with_preload(i))
55
+ end
56
+ end
57
+ end
58
+ key[0, key_size]
59
+ end
60
+
61
+ def digest
62
+ @digest ||= case algorithm
63
+ when nil then Digest::DEFAULT
64
+ when Digest then algorithm
65
+ when Symbol then Digest.for(algorithm)
66
+ when String then Digest.for(algorithm)
67
+ else Digest.for(algorithm.to_i)
68
+ end
69
+ end
70
+
71
+ def digest_input_with_preload(length = 0)
72
+ ("\0" * length) << digest_input
73
+ end
74
+
75
+ def digest_input
76
+ raise NotImplementedError
77
+ end
78
+
79
+ ##
80
+ # @see http://tools.ietf.org/html/rfc4880#section-3.7.1.1
81
+ class Simple < S2K
82
+ IDENTIFIER = 0x00
83
+
84
+ def self.parse(input)
85
+ self.new(nil, :algorithm => input.read_byte)
86
+ end
87
+
88
+ def digest_input
89
+ passphrase
90
+ end
91
+ end
92
+
93
+ ##
94
+ # @see http://tools.ietf.org/html/rfc4880#section-3.7.1.2
95
+ class Salted < S2K
96
+ IDENTIFIER = 0x01
97
+
98
+ def self.parse(input)
99
+ self.new(nil, :algorithm => input.read_byte, :salt => input.read_bytes(8))
100
+ end
101
+
102
+ attr_accessor :salt
103
+
104
+ def initialize(passphrase = nil, options = {}, &block)
105
+ super(passphrase, options, &block)
106
+
107
+ @salt = Random.bytes(8) unless @salt
108
+ end
109
+
110
+ def write(buffer)
111
+ super(buffer)
112
+ buffer.write_bytes(salt)
113
+ end
114
+
115
+ def to_hash
116
+ super.merge({:salt => salt})
117
+ end
118
+
119
+ def digest_input
120
+ salt.to_s[0, 8] << passphrase
121
+ end
122
+ end
123
+
124
+ ##
125
+ # @see http://tools.ietf.org/html/rfc4880#section-3.7.1.3
126
+ class Iterated < Salted
127
+ IDENTIFIER = 0x03
128
+
129
+ def self.parse(input)
130
+ self.new(nil, :algorithm => input.read_byte, :salt => input.read_bytes(8)) do |s2k|
131
+ s2k.count = s2k.decode_count(input.read_byte)
132
+ end
133
+ end
134
+
135
+ attr_reader :count
136
+
137
+ def initialize(passphrase = nil, options = {}, &block)
138
+ super(passphrase, options, &block)
139
+
140
+ @count = 65536 unless @count
141
+ end
142
+
143
+ def write(buffer)
144
+ super(buffer)
145
+ buffer.write_byte(encode_count(count))
146
+ end
147
+
148
+ def to_hash
149
+ super.merge(:count => count)
150
+ end
151
+
152
+ def digest_input
153
+ buffer = Buffer.write do |buffer|
154
+ iterations = count
155
+ while iterations > 0
156
+ buffer << (digest_input = super())
157
+ iterations -= digest_input.size
158
+ end
159
+ end
160
+ end
161
+
162
+ protected
163
+
164
+ EXPBIAS = 6
165
+
166
+ def decode_count(count)
167
+ (16 + (count & 15)) << ((count >> 4) + EXPBIAS)
168
+ end
169
+
170
+ def encode_count(iterations)
171
+ case iterations
172
+ when 0..1024 then 0
173
+ when 65011712..(1.0/0) then 255
174
+ else
175
+ count1 = iterations >> 6
176
+ count2 = (count2 || 0) + 1 while count1 >= 32 && count1 >>= 1
177
+ result = (count2 << 4) | (count1 - 16)
178
+ result += 1 if decode_count(result) < iterations
179
+ result
180
+ end
181
+ end
182
+ end
183
+
184
+ DEFAULT = Iterated
185
+ end
186
+ end
@@ -0,0 +1,65 @@
1
+ module OpenPGP
2
+ ##
3
+ # Alias for OpenPGP::Armor.encode().
4
+ def self.enarmor(data, marker = :message, options = {})
5
+ Armor.encode(data, marker, options)
6
+ end
7
+
8
+ ##
9
+ # Alias for OpenPGP::Armor.decode().
10
+ def self.dearmor(text, marker = nil, options = {})
11
+ Armor.decode(text, marker, options)
12
+ end
13
+
14
+ ##
15
+ # Alias for OpenPGP::Message.encrypt().
16
+ def self.encrypt(data, options = {})
17
+ (msg = Message.encrypt(data, options)) ? msg.to_s : nil
18
+ end
19
+
20
+ ##
21
+ # Alias for OpenPGP::Message.decrypt().
22
+ def self.decrypt(data, options = {})
23
+ raise NotImplementedError # TODO
24
+ end
25
+
26
+ ##
27
+ # Alias for OpenPGP::Message.sign().
28
+ def self.sign
29
+ raise NotImplementedError # TODO
30
+ end
31
+
32
+ ##
33
+ # Alias for OpenPGP::Message.verify().
34
+ def self.verify
35
+ raise NotImplementedError # TODO
36
+ end
37
+
38
+ ##
39
+ # @see http://tools.ietf.org/html/rfc4880#section-6.1
40
+ CRC24_INIT = 0x00b704ce
41
+ CRC24_POLY = 0x01864cfb
42
+
43
+ ##
44
+ # @see http://tools.ietf.org/html/rfc4880#section-6
45
+ # @see http://tools.ietf.org/html/rfc4880#section-6.1
46
+ def self.crc24(data)
47
+ crc = CRC24_INIT
48
+ data.each_byte do |octet|
49
+ crc ^= octet << 16
50
+ 8.times do
51
+ crc <<= 1
52
+ crc ^= CRC24_POLY if (crc & 0x01000000).nonzero?
53
+ end
54
+ end
55
+ crc &= 0x00ffffff
56
+ end
57
+
58
+ ##
59
+ # Returns the bit length of a multiprecision integer (MPI).
60
+ #
61
+ # @see http://tools.ietf.org/html/rfc4880#section-3.2
62
+ def self.bitlength(data)
63
+ data.empty? ? 0 : (data.size - 1) * 8 + (Math.log(data[0]) / Math.log(2)).floor + 1
64
+ end
65
+ end
@@ -0,0 +1,14 @@
1
+ module OpenPGP
2
+ module VERSION
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 1
6
+ EXTRA = nil
7
+
8
+ STRING = [MAJOR, MINOR, TINY].join('.')
9
+ STRING << "-#{EXTRA}" if EXTRA
10
+
11
+ def self.to_s() STRING end
12
+ def self.to_str() STRING end
13
+ end
14
+ end
data/lib/openpgp.rb ADDED
@@ -0,0 +1,17 @@
1
+ require 'openpgp/version'
2
+ require 'openpgp/util'
3
+
4
+ module OpenPGP
5
+ autoload :Algorithm, 'openpgp/algorithm'
6
+ autoload :Armor, 'openpgp/armor'
7
+ autoload :Buffer, 'openpgp/buffer'
8
+ autoload :Cipher, 'openpgp/cipher'
9
+ autoload :Engine, 'openpgp/engine'
10
+ autoload :Digest, 'openpgp/digest'
11
+ autoload :Message, 'openpgp/message'
12
+ autoload :Packet, 'openpgp/packet'
13
+ autoload :Random, 'openpgp/random'
14
+ autoload :S2K, 'openpgp/s2k'
15
+ end
16
+
17
+ OpenPGP::Engine::OpenSSL.install!
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: klacointe-openpgp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Arto Bendiken
8
+ - spk
9
+ - "K\xC3\xA9vin Lacointe"
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2009-04-30 00:00:00 +02:00
15
+ default_executable: openpgp
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: rakefile
19
+ type: :development
20
+ version_requirement:
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: "0"
26
+ version:
27
+ description: " OpenPGP.rb is a pure-Ruby implementation of the OpenPGP Message Format (RFC 4880).\n"
28
+ email: kevinlacointe@gmail.com
29
+ executables:
30
+ - openpgp
31
+ extensions: []
32
+
33
+ extra_rdoc_files: []
34
+
35
+ files:
36
+ - LICENSE
37
+ - README
38
+ - Rakefile
39
+ - VERSION
40
+ - bin/openpgp
41
+ - lib/openpgp/digest.rb
42
+ - lib/openpgp/engine/openssl.rb
43
+ - lib/openpgp/engine/gnupg.rb
44
+ - lib/openpgp/random.rb
45
+ - lib/openpgp/cipher.rb
46
+ - lib/openpgp/message.rb
47
+ - lib/openpgp/client/gnupg.rb
48
+ - lib/openpgp/util.rb
49
+ - lib/openpgp/version.rb
50
+ - lib/openpgp/armor.rb
51
+ - lib/openpgp/digest/rmd160.rb
52
+ - lib/openpgp/digest/sha1.rb
53
+ - lib/openpgp/digest/sha2.rb
54
+ - lib/openpgp/digest/md5.rb
55
+ - lib/openpgp/cipher/twofish.rb
56
+ - lib/openpgp/cipher/idea.rb
57
+ - lib/openpgp/cipher/3des.rb
58
+ - lib/openpgp/cipher/aes.rb
59
+ - lib/openpgp/cipher/cast5.rb
60
+ - lib/openpgp/cipher/blowfish.rb
61
+ - lib/openpgp/packet.rb
62
+ - lib/openpgp/engine.rb
63
+ - lib/openpgp/s2k.rb
64
+ - lib/openpgp/buffer.rb
65
+ - lib/openpgp/algorithm.rb
66
+ - lib/openpgp.rb
67
+ has_rdoc: true
68
+ homepage: http://github.com/klacointe/openpgp
69
+ licenses:
70
+ - MIT
71
+ post_install_message:
72
+ rdoc_options: []
73
+
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 1.8.2
81
+ version:
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: "0"
87
+ version:
88
+ requirements:
89
+ - GnuPG >= 1.4.7 (not required, but enables extra functionality)
90
+ rubyforge_project: openpgp
91
+ rubygems_version: 1.3.5
92
+ signing_key:
93
+ specification_version: 3
94
+ summary: A pure-Ruby implementation of the OpenPGP Message Format (RFC 4880).
95
+ test_files: []
96
+