iostreams 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/io_streams/pgp.rb +255 -83
- data/lib/io_streams/version.rb +1 -1
- data/lib/iostreams.rb +1 -0
- data/test/pgp_test.rb +238 -0
- data/test/zip_writer_test.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d4dcddf28ba98342cec548ede58e83e08f6d4948
|
4
|
+
data.tar.gz: 0fd6ff53b81dc4fdd8847f5c646d875aa03f7c4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09453fc367c6d133311676971c31e9135549559995f2ffbcb9960bfd6054121344c6c6b5d7eb85bfb993b1531a8d70a7299659bceb0cffb12805b9ce823ac035'
|
7
|
+
data.tar.gz: afb3e83e545230f98a6e2acf936e937d20fdc3a753607aae039788daae426cd0bbd03d5018272e0c179512b7e4b55e6a9fcc8af2ad4b83b43aa05996630de446
|
data/lib/io_streams/pgp.rb
CHANGED
@@ -62,8 +62,8 @@ module IOStreams
|
|
62
62
|
# Select highest level: 5
|
63
63
|
#
|
64
64
|
# Delete test keys:
|
65
|
-
# IOStreams::Pgp.delete_keys(email: 'sender@example.org',
|
66
|
-
# IOStreams::Pgp.delete_keys(email: 'receiver@example.org',
|
65
|
+
# IOStreams::Pgp.delete_keys(email: 'sender@example.org', private: true)
|
66
|
+
# IOStreams::Pgp.delete_keys(email: 'receiver@example.org', private: true)
|
67
67
|
#
|
68
68
|
# Limitations
|
69
69
|
# - Designed for processing larger files since a process is spawned for each file processed.
|
@@ -84,9 +84,13 @@ module IOStreams
|
|
84
84
|
class Failure < StandardError
|
85
85
|
end
|
86
86
|
|
87
|
-
|
88
|
-
|
89
|
-
|
87
|
+
class UnsupportedVersion < Failure
|
88
|
+
end
|
89
|
+
|
90
|
+
# Generate a new ultimate trusted local public and private key.
|
91
|
+
#
|
92
|
+
# Returns [String] the key id for the generated key.
|
93
|
+
# Raises an exception if it fails to generate the key.
|
90
94
|
#
|
91
95
|
# name: [String]
|
92
96
|
# Name of who owns the key, such as organization
|
@@ -105,126 +109,197 @@ module IOStreams
|
|
105
109
|
#
|
106
110
|
# See `man gpg` for the remaining options
|
107
111
|
def self.generate_key(name:, email:, comment: nil, passphrase: nil, key_type: 'RSA', key_length: 4096, subkey_type: 'RSA', subkey_length: key_length, expire_date: nil)
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
end
|
126
|
-
end
|
127
|
-
key_id
|
128
|
-
else
|
129
|
-
raise(Pgp::Failure, "GPG Failed to generate key: #{out.read.chomp}")
|
112
|
+
version_check
|
113
|
+
params = ''
|
114
|
+
params << "Key-Type: #{key_type}\n" if key_type
|
115
|
+
params << "Key-Length: #{key_length}\n" if key_length
|
116
|
+
params << "Subkey-Type: #{subkey_type}\n" if subkey_type
|
117
|
+
params << "Subkey-Length: #{subkey_length}\n" if subkey_length
|
118
|
+
params << "Name-Real: #{name}\n" if name
|
119
|
+
params << "Name-Comment: #{comment}\n" if comment
|
120
|
+
params << "Name-Email: #{email}\n" if email
|
121
|
+
params << "Expire-Date: #{expire_date}\n" if expire_date
|
122
|
+
params << "Passphrase: #{passphrase}\n" if passphrase
|
123
|
+
params << '%commit'
|
124
|
+
out, err, status = Open3.capture3('gpg --batch --gen-key', binmode: true, stdin_data: params)
|
125
|
+
logger.debug { "IOStreams::Pgp.generate_key output:\n#{out}#{err}" } if logger
|
126
|
+
if status.success?
|
127
|
+
if match = err.match(/gpg: key ([0-9A-F]+)\s+/)
|
128
|
+
return match[1]
|
130
129
|
end
|
130
|
+
else
|
131
|
+
raise(Pgp::Failure, "GPG Failed to generate key: #{out}#{err}")
|
131
132
|
end
|
132
133
|
end
|
133
134
|
|
134
|
-
# Delete
|
135
|
-
# Returns false if no key was found
|
136
|
-
# Raises an exception if it fails to delete the key
|
135
|
+
# Delete all private and public keys for a particular email.
|
137
136
|
#
|
138
|
-
#
|
137
|
+
# Returns false if no key was found.
|
138
|
+
# Raises an exception if it fails to delete the key.
|
139
|
+
#
|
140
|
+
# email: [String] Email address for the key.
|
139
141
|
#
|
140
142
|
# public: [true|false]
|
141
143
|
# Whether to delete the public key
|
142
144
|
# Default: true
|
143
145
|
#
|
144
|
-
#
|
145
|
-
# Whether to delete the
|
146
|
+
# private: [true|false]
|
147
|
+
# Whether to delete the private key
|
146
148
|
# Default: false
|
147
|
-
def self.delete_keys(email:, public: true,
|
149
|
+
def self.delete_keys(email:, public: true, private: false)
|
150
|
+
version_check
|
148
151
|
cmd = "for i in `gpg --with-colons --fingerprint #{email} | grep \"^fpr\" | cut -d: -f10`; do\n"
|
149
|
-
cmd << "gpg --batch --delete-secret-keys \"$i\" ;\n" if
|
152
|
+
cmd << "gpg --batch --delete-secret-keys \"$i\" ;\n" if private
|
150
153
|
cmd << "gpg --batch --delete-keys \"$i\" ;\n" if public
|
151
154
|
cmd << 'done'
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
155
|
+
|
156
|
+
out, err, status = Open3.capture3(cmd, binmode: true)
|
157
|
+
logger.debug { "IOStreams::Pgp.delete_keys output:\n#{err}#{out}" } if logger
|
158
|
+
|
159
|
+
if status.success?
|
160
|
+
return false if err =~ /(not found|No public key)/i
|
161
|
+
raise(Pgp::Failure, "GPG Failed to delete keys for #{email}:#{err}#{out}") if out.include?('error')
|
162
|
+
true
|
163
|
+
else
|
164
|
+
raise(Pgp::Failure, "GPG Failed calling gpg to delete private keys for #{email}: #{err}#{out}")
|
161
165
|
end
|
162
166
|
end
|
163
167
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
168
|
+
# Returns [true|false] whether their is a key for the supplied email or key_id
|
169
|
+
def self.has_key?(email: nil, key_id: nil, private: false)
|
170
|
+
raise(ArgumentError, 'Either :email, or :key_id must be supplied') if email.nil? && key_id.nil?
|
171
|
+
|
172
|
+
!list_keys(email: email, key_id: key_id, private: private).empty?
|
173
|
+
end
|
174
|
+
|
175
|
+
# Returns [Array<Hash>] the list of keys.
|
176
|
+
# Each Hash consists of:
|
177
|
+
# key_length: [Integer]
|
178
|
+
# key_type: [String]
|
179
|
+
# key_id: [String]
|
180
|
+
# date: [String]
|
181
|
+
# name: [String]
|
182
|
+
# email: [String]
|
183
|
+
# Returns [] if no keys were found.
|
184
|
+
def self.list_keys(email: nil, key_id: nil, private: false)
|
185
|
+
version_check
|
186
|
+
cmd = private ? '--list-secret-keys' : '--list-keys'
|
187
|
+
out, err, status = Open3.capture3("gpg #{cmd} #{email || key_id}", binmode: true)
|
188
|
+
logger.debug { "IOStreams::Pgp.list_keys output:\n#{err}#{out}" } if logger
|
189
|
+
if status.success? && out.length > 0
|
190
|
+
# Sample output
|
191
|
+
# pub 4096R/3A5456F5 2017-06-07
|
192
|
+
# uid [ unknown] Joe Bloggs <j@bloggs.net>
|
193
|
+
# sub 4096R/2C9B240B 2017-06-07
|
194
|
+
parse_list_output(out)
|
195
|
+
else
|
196
|
+
return [] if err =~ /(key not found|No (public|secret) key)/i
|
197
|
+
raise(Pgp::Failure, "GPG Failed calling gpg to list keys for #{email || key_id}: #{err}#{out}")
|
176
198
|
end
|
177
199
|
end
|
178
200
|
|
179
|
-
#
|
180
|
-
#
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
201
|
+
# Extract information from the supplied key.
|
202
|
+
#
|
203
|
+
# Useful for confirming encryption keys before importing them.
|
204
|
+
#
|
205
|
+
# Returns [Array<Hash>] the list of primary keys.
|
206
|
+
# Each Hash consists of:
|
207
|
+
# key_length: [Integer]
|
208
|
+
# key_type: [String]
|
209
|
+
# key_id: [String]
|
210
|
+
# date: [String]
|
211
|
+
# name: [String]
|
212
|
+
# email: [String]
|
213
|
+
def self.key_info(key:)
|
214
|
+
version_check
|
215
|
+
out, err, status = Open3.capture3('gpg', binmode: true, stdin_data: key)
|
216
|
+
logger.debug { "IOStreams::Pgp.key_info output:\n#{err}#{out}" } if logger
|
217
|
+
if status.success? && out.length > 0
|
218
|
+
# Sample Output:
|
219
|
+
#
|
220
|
+
# pub 4096R/3A5456F5 2017-06-07
|
221
|
+
# uid Joe Bloggs <j@bloggs.net>
|
222
|
+
# sub 4096R/2C9B240B 2017-06-07
|
223
|
+
parse_list_output(out)
|
224
|
+
else
|
225
|
+
raise(Pgp::Failure, "GPG Failed extracting key details: #{err} #{out}")
|
195
226
|
end
|
196
227
|
end
|
197
228
|
|
198
|
-
# Returns [String] the
|
229
|
+
# Returns [String] containing all the keys for the supplied email address.
|
199
230
|
#
|
200
|
-
# email: [String] Email address for requested key
|
231
|
+
# email: [String] Email address for requested key.
|
201
232
|
#
|
202
233
|
# ascii: [true|false]
|
203
234
|
# Whether to export as ASCII text instead of binary format
|
204
235
|
# Default: true
|
205
236
|
#
|
206
|
-
#
|
237
|
+
# private: [true|false]
|
207
238
|
# Whether to export the private key
|
208
239
|
# Default: false
|
209
|
-
def self.export(email:, ascii: true,
|
240
|
+
def self.export(email:, ascii: true, private: false)
|
241
|
+
version_check
|
210
242
|
armor = ascii ? ' --armor' : nil
|
211
|
-
cmd =
|
243
|
+
cmd = private ? '--export-secret-keys' : '--export'
|
212
244
|
out, err, status = Open3.capture3("gpg#{armor} #{cmd} #{email}", binmode: true)
|
245
|
+
logger.debug { "IOStreams::Pgp.export output:\n#{err}" } if logger
|
213
246
|
if status.success? && out.length > 0
|
214
247
|
out
|
215
248
|
else
|
216
|
-
raise(Pgp::Failure, "GPG Failed reading key: #{email}: #{err}
|
249
|
+
raise(Pgp::Failure, "GPG Failed reading key: #{email}: #{err}")
|
217
250
|
end
|
218
251
|
end
|
219
252
|
|
220
253
|
# Imports the supplied public/private key
|
221
|
-
#
|
222
|
-
|
254
|
+
#
|
255
|
+
# Returns [Array<Hash>] keys that were successfully imported.
|
256
|
+
# Each Hash consists of:
|
257
|
+
# key_id: [String]
|
258
|
+
# type: [String]
|
259
|
+
# name: [String]
|
260
|
+
# email: [String]
|
261
|
+
# Returns [] if the same key was previously imported.
|
262
|
+
#
|
263
|
+
# Raises Pgp::Failure if there was an issue importing any of the keys.
|
264
|
+
#
|
265
|
+
# Notes:
|
266
|
+
# * Importing a new key for the same email address does not remove the prior key if any.
|
267
|
+
# * Invalidated keys must be removed manually.
|
268
|
+
def self.import(key:)
|
269
|
+
version_check
|
223
270
|
out, err, status = Open3.capture3('gpg --import', binmode: true, stdin_data: key)
|
224
|
-
|
225
|
-
|
271
|
+
logger.debug { "IOStreams::Pgp.import output:\n#{err}#{out}" } if logger
|
272
|
+
if status.success? && err.length > 0
|
273
|
+
# Sample output
|
274
|
+
#
|
275
|
+
# gpg: key C16500E3: secret key imported\n"
|
276
|
+
# gpg: key C16500E3: public key "Joe Bloggs <pgp_test@iostreams.net>" imported
|
277
|
+
# gpg: Total number processed: 1
|
278
|
+
# gpg: imported: 1 (RSA: 1)
|
279
|
+
# gpg: secret keys read: 1
|
280
|
+
# gpg: secret keys imported: 1
|
281
|
+
#
|
282
|
+
# Ignores unchanged:
|
283
|
+
# gpg: key 9615D46D: \"Joe Bloggs <j@bloggs.net>\" not changed\n
|
284
|
+
results = []
|
285
|
+
secret = false
|
286
|
+
err.each_line do |line|
|
287
|
+
if line =~ /secret key imported/
|
288
|
+
secret = true
|
289
|
+
elsif match = line.match(/key\s+(\w+):\s+(\w+).+\"(.*)<(.*)>\"/)
|
290
|
+
results << {
|
291
|
+
key_id: match[1].to_s.strip,
|
292
|
+
private: secret,
|
293
|
+
name: match[3].to_s.strip,
|
294
|
+
email: match[4].to_s.strip
|
295
|
+
}
|
296
|
+
secret = false
|
297
|
+
end
|
298
|
+
end
|
299
|
+
results
|
226
300
|
else
|
227
|
-
|
301
|
+
return [] if err =~ /already in secret keyring/
|
302
|
+
raise(Pgp::Failure, "GPG Failed importing key: #{err}#{out}")
|
228
303
|
end
|
229
304
|
end
|
230
305
|
|
@@ -236,11 +311,13 @@ module IOStreams
|
|
236
311
|
# After importing keys, they are not trusted and the relevant trust level must be set.
|
237
312
|
# Default: 5 : Ultimate
|
238
313
|
def self.set_trust(email:, level: 5)
|
314
|
+
version_check
|
239
315
|
fingerprint = fingerprint(email: email)
|
240
316
|
return unless fingerprint
|
241
317
|
|
242
318
|
trust = "#{fingerprint}:#{level + 1}:\n"
|
243
319
|
out, err, status = Open3.capture3('gpg --import-ownertrust', stdin_data: trust)
|
320
|
+
logger.debug { "IOStreams::Pgp.set_trust output:\n#{err}#{out}" } if logger
|
244
321
|
if status.success?
|
245
322
|
err
|
246
323
|
else
|
@@ -248,5 +325,100 @@ module IOStreams
|
|
248
325
|
end
|
249
326
|
end
|
250
327
|
|
328
|
+
# DEPRECATED - Use key_ids instead of fingerprints
|
329
|
+
def self.fingerprint(email:)
|
330
|
+
version_check
|
331
|
+
Open3.popen2e("gpg --list-keys --fingerprint --with-colons #{email}") do |stdin, out, waith_thr|
|
332
|
+
output = out.read.chomp
|
333
|
+
if waith_thr.value.success?
|
334
|
+
output.each_line do |line|
|
335
|
+
if match = line.match(/\Afpr.*::([^\:]*):\Z/)
|
336
|
+
return match[1]
|
337
|
+
end
|
338
|
+
end
|
339
|
+
nil
|
340
|
+
else
|
341
|
+
return if output =~ /(public key not found|No public key)/i
|
342
|
+
raise(Pgp::Failure, "GPG Failed calling gpg to list keys for #{email}: #{output}")
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
def self.logger=(logger)
|
348
|
+
@logger = logger
|
349
|
+
end
|
350
|
+
|
351
|
+
# Returns [String] the version of pgp currently installed
|
352
|
+
def self.pgp_version
|
353
|
+
@pgp_version ||= begin
|
354
|
+
out, err, status = Open3.capture3("gpg --version")
|
355
|
+
logger.debug { "IOStreams::Pgp.version output:\n#{err}#{out}" } if logger
|
356
|
+
if status.success?
|
357
|
+
# Sample output
|
358
|
+
# gpg (GnuPG) 2.0.30
|
359
|
+
# libgcrypt 1.7.6
|
360
|
+
# Copyright (C) 2015 Free Software Foundation, Inc.
|
361
|
+
# License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
362
|
+
# This is free software: you are free to change and redistribute it.
|
363
|
+
# There is NO WARRANTY, to the extent permitted by law.
|
364
|
+
#
|
365
|
+
# Home: ~/.gnupg
|
366
|
+
# Supported algorithms:
|
367
|
+
# Pubkey: RSA, RSA, RSA, ELG, DSA
|
368
|
+
# Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
|
369
|
+
# CAMELLIA128, CAMELLIA192, CAMELLIA256
|
370
|
+
# Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
|
371
|
+
# Compression: Uncompressed, ZIP, ZLIB, BZIP2
|
372
|
+
if match = out.lines.first.match(/(\d+\.\d+.\d+)/)
|
373
|
+
match[1]
|
374
|
+
end
|
375
|
+
else
|
376
|
+
return [] if err =~ /(key not found|No (public|secret) key)/i
|
377
|
+
raise(Pgp::Failure, "GPG Failed calling gpg to list keys for #{email || key_id}: #{err}#{out}")
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
private
|
383
|
+
|
384
|
+
@logger = nil
|
385
|
+
|
386
|
+
def self.logger
|
387
|
+
@logger
|
388
|
+
end
|
389
|
+
|
390
|
+
def self.version_check
|
391
|
+
raise(Pgp::UnsupportedVersion, "Version #{pgp_version} of gpg is not yet supported. You are welcome to submit a Pull Request.") if pgp_version.to_f >= 2.1
|
392
|
+
end
|
393
|
+
|
394
|
+
def self.parse_list_output(out)
|
395
|
+
results = []
|
396
|
+
hash = {}
|
397
|
+
out.each_line do |line|
|
398
|
+
if match = line.match(/(pub|sec)\s+(\d+)(.*)\/(\w+)\s+(\S+)/)
|
399
|
+
hash = {
|
400
|
+
private: match[1] == 'sec',
|
401
|
+
key_length: match[2].to_s.to_i,
|
402
|
+
key_type: match[3],
|
403
|
+
key_id: match[4],
|
404
|
+
date: (Date.parse(match[5].to_s) rescue match[5])
|
405
|
+
}
|
406
|
+
elsif match = line.match(/uid\s+(.+)<(.+)>/)
|
407
|
+
name = match[1].strip
|
408
|
+
hash[:email] = match[2].strip
|
409
|
+
if match = name.match(/(\[(.+)\])?(.+)/)
|
410
|
+
trust = match[2].to_s.strip
|
411
|
+
hash[:trust] = trust unless trust.empty?
|
412
|
+
hash[:name] = match[3].to_s.strip
|
413
|
+
else
|
414
|
+
hash[:name] = name
|
415
|
+
end
|
416
|
+
results << hash
|
417
|
+
hash = {}
|
418
|
+
end
|
419
|
+
end
|
420
|
+
results
|
421
|
+
end
|
422
|
+
|
251
423
|
end
|
252
424
|
end
|
data/lib/io_streams/version.rb
CHANGED
data/lib/iostreams.rb
CHANGED
data/test/pgp_test.rb
ADDED
@@ -0,0 +1,238 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
#IOStreams::Pgp.logger = SemanticLogger[IOStreams::Pgp]
|
4
|
+
|
5
|
+
module Streams
|
6
|
+
class PgpTest < Minitest::Test
|
7
|
+
describe IOStreams::Pgp::Reader do
|
8
|
+
let :user_name do
|
9
|
+
'Joe Bloggs'
|
10
|
+
end
|
11
|
+
|
12
|
+
let :email do
|
13
|
+
'pgp_test@iostreams.net'
|
14
|
+
end
|
15
|
+
|
16
|
+
let :generated_key_id do
|
17
|
+
IOStreams::Pgp.generate_key(name: user_name, email: email, key_length: 1024)
|
18
|
+
end
|
19
|
+
|
20
|
+
let :public_key do
|
21
|
+
generated_key_id
|
22
|
+
IOStreams::Pgp.export(email: email)
|
23
|
+
end
|
24
|
+
|
25
|
+
let :private_key do
|
26
|
+
generated_key_id
|
27
|
+
IOStreams::Pgp.export(email: email, private: true)
|
28
|
+
end
|
29
|
+
|
30
|
+
before do
|
31
|
+
IOStreams::Pgp.delete_keys(email: email, public: true, private: true)
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '.pgp_version' do
|
35
|
+
it 'returns pgp version' do
|
36
|
+
assert IOStreams::Pgp.pgp_version
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '.generate_key' do
|
41
|
+
it 'returns the key id' do
|
42
|
+
assert generated_key_id
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '.has_key?' do
|
47
|
+
before do
|
48
|
+
generated_key_id
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'confirms public key' do
|
52
|
+
assert IOStreams::Pgp.has_key?(key_id: generated_key_id)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'confirms private key' do
|
56
|
+
assert IOStreams::Pgp.has_key?(key_id: generated_key_id, private: true)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '.delete_keys' do
|
61
|
+
it 'handles no keys' do
|
62
|
+
refute IOStreams::Pgp.delete_keys(email: 'random@iostreams.net', public: true, private: true)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'deletes existing keys' do
|
66
|
+
generated_key_id
|
67
|
+
assert IOStreams::Pgp.delete_keys(email: email, public: true, private: true)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'deletes just the private key' do
|
71
|
+
generated_key_id
|
72
|
+
assert IOStreams::Pgp.delete_keys(email: email, public: false, private: true)
|
73
|
+
refute IOStreams::Pgp.has_key?(key_id: generated_key_id, private: true)
|
74
|
+
assert IOStreams::Pgp.has_key?(key_id: generated_key_id, private: false)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '.export' do
|
79
|
+
before do
|
80
|
+
generated_key_id
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'exports public keys by email' do
|
84
|
+
assert ascii_keys = IOStreams::Pgp.export(email: email)
|
85
|
+
assert ascii_keys =~ /BEGIN PGP PUBLIC KEY BLOCK/, ascii_keys
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'exports private keys by email' do
|
89
|
+
assert ascii_keys = IOStreams::Pgp.export(email: email, private: true)
|
90
|
+
assert ascii_keys =~ /BEGIN PGP PRIVATE KEY BLOCK/, ascii_keys
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'exports public keys as binary' do
|
94
|
+
assert keys = IOStreams::Pgp.export(email: email, ascii: false)
|
95
|
+
refute keys =~ /BEGIN PGP (PUBLIC|PRIVATE) KEY BLOCK/, keys
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'exports private keys as binary' do
|
99
|
+
assert keys = IOStreams::Pgp.export(email: email, ascii: false, private: true)
|
100
|
+
refute keys =~ /BEGIN PGP (PUBLIC|PRIVATE) KEY BLOCK/, keys
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe '.list_keys' do
|
105
|
+
before do
|
106
|
+
generated_key_id
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'lists public keys' do
|
110
|
+
assert keys = IOStreams::Pgp.list_keys(email: email)
|
111
|
+
assert_equal 1, keys.size
|
112
|
+
assert key = keys.first
|
113
|
+
|
114
|
+
assert_equal key[:date], Date.today
|
115
|
+
assert_equal email, key[:email]
|
116
|
+
assert_equal generated_key_id, key[:key_id]
|
117
|
+
assert_equal 1024, key[:key_length]
|
118
|
+
assert_equal 'R', key[:key_type]
|
119
|
+
assert_equal user_name, key[:name]
|
120
|
+
refute key[:private], key
|
121
|
+
assert_equal 'ultimate', key[:trust]
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'lists private keys' do
|
125
|
+
assert keys = IOStreams::Pgp.list_keys(email: email, private: true)
|
126
|
+
assert_equal 1, keys.size
|
127
|
+
assert key = keys.first
|
128
|
+
|
129
|
+
assert_equal key[:date], Date.today
|
130
|
+
assert_equal email, key[:email]
|
131
|
+
assert_equal generated_key_id, key[:key_id]
|
132
|
+
assert_equal 1024, key[:key_length]
|
133
|
+
assert_equal 'R', key[:key_type]
|
134
|
+
assert_equal user_name, key[:name]
|
135
|
+
assert key[:private], key
|
136
|
+
refute key.key?(:trust)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe '.key_info' do
|
141
|
+
it 'extracts public key info' do
|
142
|
+
assert keys = IOStreams::Pgp.key_info(key: public_key)
|
143
|
+
assert_equal 1, keys.size
|
144
|
+
assert key = keys.first
|
145
|
+
|
146
|
+
assert_equal key[:date], Date.today
|
147
|
+
assert_equal email, key[:email]
|
148
|
+
assert_equal generated_key_id, key[:key_id]
|
149
|
+
assert_equal 1024, key[:key_length]
|
150
|
+
assert_equal 'R', key[:key_type]
|
151
|
+
assert_equal user_name, key[:name]
|
152
|
+
refute key[:private], key
|
153
|
+
refute key.key?(:trust)
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'extracts private key info' do
|
157
|
+
assert keys = IOStreams::Pgp.key_info(key: private_key)
|
158
|
+
assert_equal 1, keys.size
|
159
|
+
assert key = keys.first
|
160
|
+
|
161
|
+
assert_equal key[:date], Date.today
|
162
|
+
assert_equal email, key[:email]
|
163
|
+
assert_equal generated_key_id, key[:key_id]
|
164
|
+
assert_equal 1024, key[:key_length]
|
165
|
+
assert_equal 'R', key[:key_type]
|
166
|
+
assert_equal user_name, key[:name]
|
167
|
+
assert key[:private], key
|
168
|
+
refute key.key?(:trust)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe '.import' do
|
173
|
+
it 'handle duplicate public key' do
|
174
|
+
generated_key_id
|
175
|
+
assert_equal [], IOStreams::Pgp.import(key: public_key)
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'handle duplicate private key' do
|
179
|
+
generated_key_id
|
180
|
+
assert_equal [], IOStreams::Pgp.import(key: private_key)
|
181
|
+
end
|
182
|
+
|
183
|
+
describe 'without keys' do
|
184
|
+
before do
|
185
|
+
@public_key = public_key
|
186
|
+
@private_key = private_key
|
187
|
+
IOStreams::Pgp.delete_keys(email: email, public: true, private: true)
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'imports ascii public key' do
|
191
|
+
assert keys = IOStreams::Pgp.import(key: @public_key)
|
192
|
+
assert_equal 1, keys.size
|
193
|
+
assert key = keys.first
|
194
|
+
|
195
|
+
assert_equal email, key[:email]
|
196
|
+
assert_equal generated_key_id, key[:key_id]
|
197
|
+
assert_equal user_name, key[:name]
|
198
|
+
refute key[:private], key
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'imports ascii private key' do
|
202
|
+
assert keys = IOStreams::Pgp.import(key: @private_key)
|
203
|
+
assert_equal 1, keys.size
|
204
|
+
assert key = keys.first
|
205
|
+
|
206
|
+
assert_equal email, key[:email]
|
207
|
+
assert_equal generated_key_id, key[:key_id]
|
208
|
+
assert_equal user_name, key[:name]
|
209
|
+
assert key[:private], key
|
210
|
+
end
|
211
|
+
|
212
|
+
it 'imports binary public key' do
|
213
|
+
assert keys = IOStreams::Pgp.import(key: @public_key)
|
214
|
+
assert_equal 1, keys.size
|
215
|
+
assert key = keys.first
|
216
|
+
|
217
|
+
assert_equal email, key[:email]
|
218
|
+
assert_equal generated_key_id, key[:key_id]
|
219
|
+
assert_equal user_name, key[:name]
|
220
|
+
refute key[:private], key
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'imports binary private key' do
|
224
|
+
assert keys = IOStreams::Pgp.import(key: @private_key)
|
225
|
+
assert_equal 1, keys.size
|
226
|
+
assert key = keys.first
|
227
|
+
|
228
|
+
assert_equal email, key[:email]
|
229
|
+
assert_equal generated_key_id, key[:key_id]
|
230
|
+
assert_equal user_name, key[:name]
|
231
|
+
assert key[:private], key
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
data/test/zip_writer_test.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iostreams
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Reid Morrison
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- test/gzip_writer_test.rb
|
70
70
|
- test/io_streams_test.rb
|
71
71
|
- test/pgp_reader_test.rb
|
72
|
+
- test/pgp_test.rb
|
72
73
|
- test/pgp_writer_test.rb
|
73
74
|
- test/test_helper.rb
|
74
75
|
- test/xlsx_reader_test.rb
|
@@ -116,6 +117,7 @@ test_files:
|
|
116
117
|
- test/gzip_writer_test.rb
|
117
118
|
- test/io_streams_test.rb
|
118
119
|
- test/pgp_reader_test.rb
|
120
|
+
- test/pgp_test.rb
|
119
121
|
- test/pgp_writer_test.rb
|
120
122
|
- test/test_helper.rb
|
121
123
|
- test/xlsx_reader_test.rb
|