rnp 0.2.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.adoc +5 -0
- data/LICENSE.txt +21 -0
- data/README.adoc +3 -182
- data/lib/rnp.rb +12 -3
- data/lib/rnp/error.rb +40 -0
- data/lib/rnp/ffi/librnp.rb +306 -0
- data/lib/rnp/input.rb +99 -0
- data/lib/rnp/key.rb +275 -0
- data/lib/rnp/misc.rb +71 -0
- data/lib/rnp/op/encrypt.rb +181 -0
- data/lib/rnp/op/sign.rb +139 -0
- data/lib/rnp/op/verify.rb +147 -0
- data/lib/rnp/output.rb +121 -0
- data/lib/rnp/rnp.rb +595 -0
- data/lib/rnp/utils.rb +44 -0
- data/lib/rnp/version.rb +8 -3
- metadata +124 -50
- data/.gitignore +0 -12
- data/.rspec +0 -2
- data/.travis.yml +0 -5
- data/CODE_OF_CONDUCT.md +0 -74
- data/Gemfile +0 -4
- data/Rakefile +0 -6
- data/Use_Cases.adoc +0 -119
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/example-usage.rb +0 -766
- data/examples/highlevel/decrypt_mem.rb +0 -44
- data/examples/highlevel/encrypt_mem.rb +0 -46
- data/examples/lowlevel/decrypt_file.rb +0 -76
- data/examples/lowlevel/decrypt_mem.rb +0 -80
- data/examples/lowlevel/encrypt_file.rb +0 -68
- data/examples/lowlevel/encrypt_mem.rb +0 -75
- data/examples/lowlevel/load_pubkey.rb +0 -118
- data/examples/lowlevel/print_keyring_file.rb +0 -68
- data/examples/lowlevel/print_keyring_mem.rb +0 -96
- data/examples/lowlevel/sign_file.rb +0 -104
- data/examples/lowlevel/sign_mem.rb +0 -96
- data/examples/lowlevel/verify_file.rb +0 -55
- data/examples/lowlevel/verify_mem.rb +0 -61
- data/lib/rnp/highlevel.rb +0 -5
- data/lib/rnp/highlevel/constants.rb +0 -96
- data/lib/rnp/highlevel/keyring.rb +0 -259
- data/lib/rnp/highlevel/publickey.rb +0 -150
- data/lib/rnp/highlevel/secretkey.rb +0 -318
- data/lib/rnp/highlevel/utils.rb +0 -119
- data/lib/rnp/lowlevel.rb +0 -6
- data/lib/rnp/lowlevel/constants.rb +0 -11
- data/lib/rnp/lowlevel/dynarray.rb +0 -129
- data/lib/rnp/lowlevel/enums.rb +0 -243
- data/lib/rnp/lowlevel/libc.rb +0 -28
- data/lib/rnp/lowlevel/libopenssl.rb +0 -15
- data/lib/rnp/lowlevel/librnp.rb +0 -213
- data/lib/rnp/lowlevel/structs.rb +0 -541
- data/lib/rnp/lowlevel/utils.rb +0 -25
- data/rnp.gemspec +0 -35
- data/rnp/lib/rnp.rb +0 -5
- data/rnp/spec/rnp_spec.rb +0 -11
data/lib/rnp/highlevel.rb
DELETED
@@ -1,96 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
|
3
|
-
module RNP
|
4
|
-
|
5
|
-
class PublicKeyAlgorithm
|
6
|
-
NONE = 0
|
7
|
-
RSA = 1
|
8
|
-
RSA_ENCRYPT_ONLY = 2
|
9
|
-
RSA_SIGN_ONLY = 3
|
10
|
-
ELGAMAL = 16
|
11
|
-
DSA = 17
|
12
|
-
ECDH = 18
|
13
|
-
ECDSA = 19
|
14
|
-
FORMERLY_ELGAMAL = 20
|
15
|
-
|
16
|
-
def self.from_native(alg)
|
17
|
-
raise if alg.class != Symbol
|
18
|
-
LibRNP::PGP_PUBKEY_ALG_T[alg]
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.to_native(alg)
|
22
|
-
# avoid a warning on newer versions of ruby
|
23
|
-
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
|
24
|
-
raise if alg.class != Integer
|
25
|
-
else
|
26
|
-
raise if alg.class != Fixnum
|
27
|
-
end
|
28
|
-
LibRNP::PGP_PUBKEY_ALG_T[alg]
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
class HashAlgorithm
|
34
|
-
MD5 = 1
|
35
|
-
SHA1 = 2
|
36
|
-
RIPEMD = 3
|
37
|
-
SHA256 = 8
|
38
|
-
SHA384 = 9
|
39
|
-
SHA512 = 10
|
40
|
-
SHA224 = 11
|
41
|
-
|
42
|
-
# see pgp_str_to_hash_alg
|
43
|
-
STRING_MAPPING = {
|
44
|
-
MD5 => 'md5',
|
45
|
-
SHA1 => 'sha1',
|
46
|
-
SHA256 => 'sha256',
|
47
|
-
SHA384 => 'sha384',
|
48
|
-
SHA512 => 'sha512'
|
49
|
-
}
|
50
|
-
|
51
|
-
def self.to_s(alg)
|
52
|
-
STRING_MAPPING[alg]
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
class SymmetricKeyAlgorithm
|
58
|
-
PLAINTEXT = 0
|
59
|
-
IDEA = 1
|
60
|
-
TRIPLEDES = 2
|
61
|
-
CAST5 = 3
|
62
|
-
BLOWFISH = 4
|
63
|
-
AES128 = 7
|
64
|
-
AES192 = 8
|
65
|
-
AES256 = 9
|
66
|
-
TWOFISH256 = 10
|
67
|
-
|
68
|
-
# see pgp_str_to_cipher
|
69
|
-
STRING_MAPPING = {
|
70
|
-
IDEA => 'idea',
|
71
|
-
TRIPLEDES => 'tripledes',
|
72
|
-
CAST5 => 'cast5',
|
73
|
-
AES128 => 'aes128',
|
74
|
-
AES256 => 'aes256'
|
75
|
-
}
|
76
|
-
|
77
|
-
def self.to_s(alg)
|
78
|
-
STRING_MAPPING[alg]
|
79
|
-
end
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
class StringToKeyUsage
|
84
|
-
NONE = 0
|
85
|
-
ENCRYPTED_AND_HASHED = 254
|
86
|
-
ENCRYPTED = 255
|
87
|
-
end
|
88
|
-
|
89
|
-
class StringToKeySpecifier
|
90
|
-
SIMPLE = 0
|
91
|
-
SALTED = 1
|
92
|
-
ITERATED_AND_SALTED = 3
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|
96
|
-
|
@@ -1,259 +0,0 @@
|
|
1
|
-
require 'English'
|
2
|
-
require 'forwardable'
|
3
|
-
|
4
|
-
module RNP
|
5
|
-
|
6
|
-
class Keyring
|
7
|
-
extend Forwardable
|
8
|
-
delegate [:size, :each, :select, :[], :push, :clear] => :@keys
|
9
|
-
|
10
|
-
attr_reader :keys
|
11
|
-
|
12
|
-
def initialize
|
13
|
-
@keys = []
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.load(data, armored=true, &passphrase_provider)
|
17
|
-
kr = Keyring.new
|
18
|
-
kr.add(data, armored, &passphrase_provider)
|
19
|
-
kr
|
20
|
-
end
|
21
|
-
|
22
|
-
def add(data, armored=true, &passphrase_provider)
|
23
|
-
keys = RNP::load_keys(data, armored, &passphrase_provider)
|
24
|
-
@keys.push(*keys)
|
25
|
-
keys.size
|
26
|
-
end
|
27
|
-
|
28
|
-
def verify(data, armored=true)
|
29
|
-
RNP::verify(@keys, data, armored)
|
30
|
-
end
|
31
|
-
|
32
|
-
def export(key, armored=true)
|
33
|
-
raise if key.parent
|
34
|
-
is_public = key.is_a?(PublicKey)
|
35
|
-
if is_public
|
36
|
-
seckey = secret_keys.find {|sk| sk.key_id == key.key_id}
|
37
|
-
else
|
38
|
-
seckey = key
|
39
|
-
end
|
40
|
-
return nil if not seckey
|
41
|
-
output_ptr = FFI::MemoryPointer.new(:pointer)
|
42
|
-
mem_ptr = FFI::MemoryPointer.new(:pointer)
|
43
|
-
output = nil
|
44
|
-
mem = nil
|
45
|
-
decrypted_seckey = nil
|
46
|
-
begin
|
47
|
-
LibRNP::pgp_setup_memory_write(output_ptr, mem_ptr, 4096)
|
48
|
-
output = LibRNP::PGPOutput.new(output_ptr.read_pointer)
|
49
|
-
mem = LibRNP::PGPMemory.new(mem_ptr.read_pointer)
|
50
|
-
native_ptr = LibC::calloc(1, LibRNP::PGPKey.size)
|
51
|
-
native = LibRNP::PGPKey.new(native_ptr)
|
52
|
-
native_auto = FFI::AutoPointer.new(native_ptr, LibRNP::PGPKey.method(:release))
|
53
|
-
key.to_native_key(native)
|
54
|
-
decrypted_seckey = seckey.decrypted_seckey
|
55
|
-
return nil if not decrypted_seckey
|
56
|
-
# this is necessary for signatures
|
57
|
-
seckey = SecretKey.from_native(decrypted_seckey)
|
58
|
-
seckey.to_native(native[:key][:seckey])
|
59
|
-
native[:type] = :PGP_PTAG_CT_SECRET_KEY
|
60
|
-
if is_public
|
61
|
-
LibRNP::dynarray_clear(native, 'uid', :string)
|
62
|
-
key.userids.each {|userid|
|
63
|
-
LibRNP::pgp_add_selfsigned_userid(native, userid)
|
64
|
-
}
|
65
|
-
end
|
66
|
-
# PGPKeyring is a ManagedStruct
|
67
|
-
subkeysring_ptr = LibC::calloc(1, LibRNP::PGPKeyring.size)
|
68
|
-
subkeysring = LibRNP::PGPKeyring.new(subkeysring_ptr)
|
69
|
-
RNP::keys_to_native_keyring(key.subkeys, subkeysring)
|
70
|
-
# add a binding signature to each subkey
|
71
|
-
(0..LibRNP::dynarray_count(subkeysring, 'key') - 1).each {|n|
|
72
|
-
subkey = LibRNP::dynarray_get_item(subkeysring, 'key', LibRNP::PGPKey, n)
|
73
|
-
LibRNP::dynarray_clear(subkey, 'packet', LibRNP::PGPSubPacket)
|
74
|
-
RNP::add_subkey_signature(native, subkey)
|
75
|
-
}
|
76
|
-
if is_public
|
77
|
-
ret = LibRNP::pgp_write_xfer_pubkey(output, native, subkeysring, armored ? 1 : 0)
|
78
|
-
else
|
79
|
-
decrypted_key_ptr = LibC::calloc(1, LibRNP::PGPKey.size)
|
80
|
-
decrypted_key = LibRNP::PGPKey.new(decrypted_key_ptr)
|
81
|
-
decrypted_key_auto = FFI::AutoPointer.new(decrypted_key_ptr, LibRNP::PGPKey.method(:release))
|
82
|
-
seckey.to_native_key(decrypted_key)
|
83
|
-
key.userids.each {|userid|
|
84
|
-
LibRNP::pgp_add_selfsigned_userid(decrypted_key, userid)
|
85
|
-
}
|
86
|
-
decrypted_key[:key][:seckey][:s2k_usage] = :PGP_S2KU_ENCRYPTED_AND_HASHED
|
87
|
-
decrypted_key[:key][:seckey][:alg] = :PGP_SA_CAST5
|
88
|
-
decrypted_key[:key][:seckey][:s2k_specifier] = :PGP_S2KS_SALTED
|
89
|
-
(0..LibRNP::dynarray_count(subkeysring, 'key') - 1).each {|n|
|
90
|
-
subkey = LibRNP::dynarray_get_item(subkeysring, 'key', LibRNP::PGPKey, n)
|
91
|
-
subkey[:key][:seckey][:s2k_usage] = :PGP_S2KU_ENCRYPTED_AND_HASHED
|
92
|
-
subkey[:key][:seckey][:alg] = :PGP_SA_CAST5
|
93
|
-
subkey[:key][:seckey][:s2k_specifier] = :PGP_S2KS_SALTED
|
94
|
-
}
|
95
|
-
ret = LibRNP::pgp_write_xfer_seckey(output, decrypted_key, key.passphrase, key.passphrase.size, subkeysring, armored ? 1 : 0)
|
96
|
-
end
|
97
|
-
return nil if ret != 1
|
98
|
-
data = mem[:buf].read_bytes(mem[:length])
|
99
|
-
data
|
100
|
-
ensure
|
101
|
-
LibRNP::pgp_teardown_memory_write(output, mem) if mem
|
102
|
-
LibRNP::pgp_seckey_free(decrypted_seckey) if decrypted_seckey
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def public_keys
|
107
|
-
self.select {|key|
|
108
|
-
key.is_a?(PublicKey)
|
109
|
-
}
|
110
|
-
end
|
111
|
-
|
112
|
-
def secret_keys
|
113
|
-
self.select {|key|
|
114
|
-
key.is_a?(SecretKey)
|
115
|
-
}
|
116
|
-
end
|
117
|
-
|
118
|
-
def to_native(native)
|
119
|
-
keys_to_native_keyring(@keys, native)
|
120
|
-
end
|
121
|
-
|
122
|
-
end
|
123
|
-
|
124
|
-
PARSE_KEYRING = Proc.new do |state, passphrase_provider, pkt, data|
|
125
|
-
next :PGP_RELEASE_MEMORY if state[:errors].any?
|
126
|
-
|
127
|
-
begin
|
128
|
-
lastkey = state[:keys].last
|
129
|
-
case pkt[:tag]
|
130
|
-
when :PGP_PTAG_CT_PUBLIC_KEY
|
131
|
-
key = PublicKey::from_native(pkt[:u][:pubkey])
|
132
|
-
state[:keys].push(key)
|
133
|
-
when :PGP_PTAG_CT_PUBLIC_SUBKEY
|
134
|
-
key = PublicKey::from_native(pkt[:u][:pubkey])
|
135
|
-
lastkey.add_subkey(key)
|
136
|
-
state[:keys].push(key)
|
137
|
-
when :PGP_PTAG_CT_ENCRYPTED_SECRET_KEY
|
138
|
-
key = SecretKey::from_native(pkt[:u][:seckey], true)
|
139
|
-
state[:keys].push(key)
|
140
|
-
when :PGP_PTAG_CT_ENCRYPTED_SECRET_SUBKEY
|
141
|
-
key = SecretKey::from_native(pkt[:u][:seckey], true)
|
142
|
-
lastkey.add_subkey(key)
|
143
|
-
state[:keys].push(key)
|
144
|
-
when :PGP_PTAG_CT_SECRET_KEY
|
145
|
-
key = SecretKey::from_native(pkt[:u][:seckey])
|
146
|
-
if state[:passphrase]
|
147
|
-
key.passphrase = state[:passphrase]
|
148
|
-
state[:passphrase] = nil
|
149
|
-
end
|
150
|
-
state[:keys].push(key)
|
151
|
-
when :PGP_PTAG_CT_SECRET_SUBKEY
|
152
|
-
key = SecretKey::from_native(pkt[:u][:seckey])
|
153
|
-
lastkey.add_subkey(key)
|
154
|
-
state[:keys].push(key)
|
155
|
-
when :PGP_GET_PASSPHRASE
|
156
|
-
seckey_ptr = pkt[:u][:skey_passphrase][:seckey]
|
157
|
-
seckey = LibRNP::PGPSecKey.new(seckey_ptr)
|
158
|
-
key = SecretKey::from_native(seckey)
|
159
|
-
passphrase = passphrase_provider.call(key)
|
160
|
-
if passphrase and passphrase != ''
|
161
|
-
passphrase_mem = LibC::calloc(1, passphrase.bytesize + 1)
|
162
|
-
passphrase_mem.write_bytes(passphrase)
|
163
|
-
pkt[:u][:skey_passphrase][:passphrase].write_pointer(passphrase_mem)
|
164
|
-
state[:passphrase] = passphrase
|
165
|
-
next :PGP_KEEP_MEMORY
|
166
|
-
end
|
167
|
-
when :PGP_PARSER_PACKET_END
|
168
|
-
if lastkey.is_a? RNP::SecretKey
|
169
|
-
raw_packet = pkt[:u][:packet]
|
170
|
-
bytes = raw_packet[:raw].read_bytes(raw_packet[:length])
|
171
|
-
lastkey.raw_subpackets.push(bytes)
|
172
|
-
end
|
173
|
-
when :PGP_PTAG_CT_USER_ID
|
174
|
-
lastkey.userids.push(pkt[:u][:userid].force_encoding('utf-8'))
|
175
|
-
when :PGP_PTAG_SS_KEY_EXPIRY
|
176
|
-
lastkey.expiration_time = lastkey.creation_time + pkt[:u][:ss_time]
|
177
|
-
else
|
178
|
-
# For debugging
|
179
|
-
#puts "Unhandled tag: #{pkt[:tag]}"
|
180
|
-
end # case
|
181
|
-
rescue
|
182
|
-
state[:errors].push($ERROR_INFO)
|
183
|
-
end
|
184
|
-
next :PGP_RELEASE_MEMORY
|
185
|
-
end
|
186
|
-
|
187
|
-
DEFAULT_PASSPHRASE_PROVIDER = Proc.new do |seckey|
|
188
|
-
nil
|
189
|
-
end
|
190
|
-
|
191
|
-
def self.load_keys(data, armored=true, &passphrase_provider)
|
192
|
-
# Just for readability
|
193
|
-
print_errors = 0
|
194
|
-
stream_mem = LibC::calloc(1, LibRNP::PGPStream.size)
|
195
|
-
# This will free the above memory (PGPStream is a ManagedStruct)
|
196
|
-
stream = LibRNP::PGPStream.new(stream_mem)
|
197
|
-
stream[:readinfo][:accumulate] = 1
|
198
|
-
LibRNP::pgp_parse_options(stream, :PGP_PTAG_SS_ALL, :PGP_PARSE_PARSED)
|
199
|
-
|
200
|
-
# This memory will be GC'd
|
201
|
-
mem = FFI::MemoryPointer.new(:uint8, data.bytesize)
|
202
|
-
mem.write_bytes(data)
|
203
|
-
|
204
|
-
LibRNP::pgp_reader_set_memory(stream, mem, mem.size)
|
205
|
-
state = {keys: [], errors: []}
|
206
|
-
provider = block_given? ? passphrase_provider : DEFAULT_PASSPHRASE_PROVIDER
|
207
|
-
callback = RNP::PARSE_KEYRING.curry[state][provider]
|
208
|
-
LibRNP::pgp_set_callback(stream, callback, nil)
|
209
|
-
LibRNP::pgp_reader_push_dearmour(stream) if armored
|
210
|
-
if LibRNP::pgp_parse(stream, print_errors) != 1
|
211
|
-
state[:errors].push('pgp_parse failed')
|
212
|
-
end
|
213
|
-
LibRNP::pgp_reader_pop_dearmour(stream) if armored
|
214
|
-
|
215
|
-
errors = stream_errors(stream)
|
216
|
-
state[:errors].push(errors) if errors.any?
|
217
|
-
|
218
|
-
raise state[:errors].join("\n") if state[:errors].any?
|
219
|
-
state[:keys]
|
220
|
-
end
|
221
|
-
|
222
|
-
def self.keys_to_native_keyring(keys, native)
|
223
|
-
raise if not native[:keys].null?
|
224
|
-
|
225
|
-
for key in keys
|
226
|
-
native_key = LibRNP::PGPKey.new
|
227
|
-
key.to_native_key(native_key)
|
228
|
-
LibRNP::dynarray_append_item(native, 'key', LibRNP::PGPKey, native_key)
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
def self.verify(keys, data, armored=true)
|
233
|
-
native_keyring_ptr = LibC::calloc(1, LibRNP::PGPKeyring.size)
|
234
|
-
native_keyring = LibRNP::PGPKeyring.new(native_keyring_ptr)
|
235
|
-
RNP::keys_to_native_keyring(keys, native_keyring)
|
236
|
-
|
237
|
-
pgpio = LibRNP::PGPIO.new
|
238
|
-
pgpio[:outs] = LibC::fdopen($stdout.to_i, 'w')
|
239
|
-
pgpio[:errs] = LibC::fdopen($stderr.to_i, 'w')
|
240
|
-
pgpio[:res] = pgpio[:errs]
|
241
|
-
|
242
|
-
data_buf = FFI::MemoryPointer.new(:uint8, data.bytesize)
|
243
|
-
data_buf.write_bytes(data)
|
244
|
-
|
245
|
-
# pgp_validate_mem frees this
|
246
|
-
mem_ptr = LibC::calloc(1, LibRNP::PGPMemory.size)
|
247
|
-
mem = LibRNP::PGPMemory.new(mem_ptr)
|
248
|
-
LibRNP::pgp_memory_add(mem, data_buf, data_buf.size)
|
249
|
-
|
250
|
-
# ManagedStruct, this frees itself
|
251
|
-
result_ptr = LibC::calloc(1, LibRNP::PGPValidation.size)
|
252
|
-
result = LibRNP::PGPValidation.new(result_ptr)
|
253
|
-
|
254
|
-
ret = LibRNP::pgp_validate_mem(pgpio, result, mem, nil, armored ? 1 : 0, native_keyring)
|
255
|
-
ret == 1
|
256
|
-
end
|
257
|
-
|
258
|
-
end # module RNP
|
259
|
-
|
@@ -1,150 +0,0 @@
|
|
1
|
-
module RNP
|
2
|
-
|
3
|
-
require_relative 'utils'
|
4
|
-
|
5
|
-
class PublicKey
|
6
|
-
attr_accessor :version,
|
7
|
-
:creation_time,
|
8
|
-
:expiration_time,
|
9
|
-
:public_key_algorithm,
|
10
|
-
:mpi,
|
11
|
-
:userids,
|
12
|
-
:parent,
|
13
|
-
:subkeys
|
14
|
-
|
15
|
-
def initialize
|
16
|
-
@version = nil
|
17
|
-
@creation_time = nil
|
18
|
-
@expiration_time = 0
|
19
|
-
@public_key_algorithm = nil
|
20
|
-
@mpi = {}
|
21
|
-
@userids = []
|
22
|
-
@parent = nil
|
23
|
-
@subkeys = []
|
24
|
-
end
|
25
|
-
|
26
|
-
def fingerprint
|
27
|
-
fp = LibRNP::PGPFingerprint.new
|
28
|
-
native_pubkey_ptr = LibC::calloc(1, LibRNP::PGPPubKey.size)
|
29
|
-
native_pubkey = LibRNP::PGPPubKey.new(native_pubkey_ptr)
|
30
|
-
native_pubkey_auto = FFI::AutoPointer.new(native_pubkey_ptr, LibRNP::PGPPubKey.method(:release))
|
31
|
-
to_native(native_pubkey)
|
32
|
-
hash = @version == 3 ? :PGP_HASH_MD5 : :PGP_HASH_SHA1
|
33
|
-
ret = LibRNP::pgp_fingerprint(fp, native_pubkey, hash)
|
34
|
-
raise 'pgp_fingerprint failed' if ret != 1
|
35
|
-
fp[:fingerprint].to_s[0, fp[:length]]
|
36
|
-
end
|
37
|
-
|
38
|
-
def fingerprint_hex
|
39
|
-
fingerprint.bytes.collect {|byte| '%02X' % byte}.join
|
40
|
-
end
|
41
|
-
|
42
|
-
def key_id
|
43
|
-
keyid_ptr = FFI::MemoryPointer.new(:uint8, LibRNP::PGP_KEY_ID_SIZE)
|
44
|
-
native_pubkey = LibRNP::PGPPubKey.new
|
45
|
-
to_native(native_pubkey)
|
46
|
-
ret = LibRNP::pgp_keyid(keyid_ptr, LibRNP::PGP_KEY_ID_SIZE, native_pubkey, :PGP_HASH_SHA1)
|
47
|
-
raise 'pgp_keyid failed' if ret != 1
|
48
|
-
keyid_ptr.read_bytes(LibRNP::PGP_KEY_ID_SIZE)
|
49
|
-
end
|
50
|
-
|
51
|
-
def key_id_hex
|
52
|
-
key_id.bytes.collect {|byte| '%02X' % byte}.join
|
53
|
-
end
|
54
|
-
|
55
|
-
def key_length
|
56
|
-
case @public_key_algorithm
|
57
|
-
when PublicKeyAlgorithm::RSA,
|
58
|
-
PublicKeyAlgorithm::RSA_ENCRYPT_ONLY,
|
59
|
-
PublicKeyAlgorithm::RSA_SIGN_ONLY
|
60
|
-
return RNP::bignum_byte_count(@mpi[:n]) * 8
|
61
|
-
when PublicKeyAlgorithm::DSA
|
62
|
-
case RNP::bignum_byte_count(@mpi[:q])
|
63
|
-
when 20
|
64
|
-
1024
|
65
|
-
when 28
|
66
|
-
2048
|
67
|
-
when 32
|
68
|
-
3072
|
69
|
-
end
|
70
|
-
when PublicKeyAlgorithm::ELGAMAL
|
71
|
-
RNP::bignum_byte_count(@mpi[:y]) * 8
|
72
|
-
end
|
73
|
-
0
|
74
|
-
end
|
75
|
-
|
76
|
-
def encrypt(data, armored=true, sk_algorithm=SymmetricKeyAlgorithm::CAST5)
|
77
|
-
cipher = SymmetricKeyAlgorithm::to_s(sk_algorithm)
|
78
|
-
memory = nil
|
79
|
-
|
80
|
-
begin
|
81
|
-
pubkey_ptr = LibC::calloc(1, LibRNP::PGPKey.size)
|
82
|
-
pubkey = LibRNP::PGPKey.new(pubkey_ptr)
|
83
|
-
pubkey_auto = FFI::AutoPointer.new(pubkey_ptr, LibRNP::PGPKey.method(:release))
|
84
|
-
|
85
|
-
to_native_key(pubkey)
|
86
|
-
data_buf = FFI::MemoryPointer.new(:uint8, data.bytesize)
|
87
|
-
data_buf.write_bytes(data)
|
88
|
-
pgpio = LibRNP::PGPIO.new
|
89
|
-
pgpio[:outs] = LibC::fdopen($stdout.to_i, 'w')
|
90
|
-
pgpio[:errs] = LibC::fdopen($stderr.to_i, 'w')
|
91
|
-
pgpio[:res] = pgpio[:errs]
|
92
|
-
memory_ptr = LibRNP::pgp_encrypt_buf(pgpio, data_buf, data_buf.size, pubkey, armored ? 1 : 0, cipher)
|
93
|
-
return nil if memory_ptr.null?
|
94
|
-
memory = LibRNP::PGPMemory.new(memory_ptr)
|
95
|
-
memory[:buf].read_bytes(memory[:length])
|
96
|
-
ensure
|
97
|
-
LibRNP::pgp_memory_free(memory) if memory
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def verify(data, armored=true)
|
102
|
-
RNP::verify([self], data, armored)
|
103
|
-
end
|
104
|
-
|
105
|
-
def add_subkey(subkey)
|
106
|
-
raise if subkey.subkeys.any?
|
107
|
-
subkey.parent = self
|
108
|
-
subkey.userids = @userids
|
109
|
-
@subkeys.push(subkey)
|
110
|
-
end
|
111
|
-
|
112
|
-
def self.from_native(native)
|
113
|
-
pubkey = PublicKey.new
|
114
|
-
pubkey.version = LibRNP::enum_value(native[:version])
|
115
|
-
pubkey.creation_time = Time.at(native[:birthtime])
|
116
|
-
if pubkey.version == 3
|
117
|
-
pubkey.expiration_time = Time.at(native[:birthtime]) + (native[:days_valid] * 86400)
|
118
|
-
end
|
119
|
-
pubkey.public_key_algorithm = PublicKeyAlgorithm::from_native(native[:alg])
|
120
|
-
pubkey.mpi = RNP::mpis_from_native(native[:alg], native)
|
121
|
-
pubkey
|
122
|
-
end
|
123
|
-
|
124
|
-
def to_native(native)
|
125
|
-
native[:version] = @version
|
126
|
-
native[:birthtime] = @creation_time.to_i
|
127
|
-
if @version == 3 and @expiration_time
|
128
|
-
native[:days_valid] = ((@expiration_time.to_i - @creation_time.to_i) / 86400).to_i
|
129
|
-
else
|
130
|
-
native[:duration] = (@expiration_time.to_i - @creation_time.to_i).to_i
|
131
|
-
end
|
132
|
-
native[:alg] = @public_key_algorithm
|
133
|
-
RNP::mpis_to_native(native[:alg], @mpi, native)
|
134
|
-
end
|
135
|
-
|
136
|
-
def to_native_key(native_key)
|
137
|
-
native_key[:type] = :PGP_PTAG_CT_PUBLIC_KEY
|
138
|
-
native_key[:sigid] = key_id
|
139
|
-
to_native(native_key[:key][:pubkey])
|
140
|
-
if not @parent
|
141
|
-
@userids.each {|userid|
|
142
|
-
LibRNP::dynarray_append_item(native_key, 'uid', :string, userid)
|
143
|
-
}
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
end
|
148
|
-
|
149
|
-
end # module RNP
|
150
|
-
|