rnp 0.2.0 → 1.0.0

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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.adoc +5 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.adoc +3 -182
  5. data/lib/rnp.rb +12 -3
  6. data/lib/rnp/error.rb +40 -0
  7. data/lib/rnp/ffi/librnp.rb +306 -0
  8. data/lib/rnp/input.rb +99 -0
  9. data/lib/rnp/key.rb +275 -0
  10. data/lib/rnp/misc.rb +71 -0
  11. data/lib/rnp/op/encrypt.rb +181 -0
  12. data/lib/rnp/op/sign.rb +139 -0
  13. data/lib/rnp/op/verify.rb +147 -0
  14. data/lib/rnp/output.rb +121 -0
  15. data/lib/rnp/rnp.rb +595 -0
  16. data/lib/rnp/utils.rb +44 -0
  17. data/lib/rnp/version.rb +8 -3
  18. metadata +124 -50
  19. data/.gitignore +0 -12
  20. data/.rspec +0 -2
  21. data/.travis.yml +0 -5
  22. data/CODE_OF_CONDUCT.md +0 -74
  23. data/Gemfile +0 -4
  24. data/Rakefile +0 -6
  25. data/Use_Cases.adoc +0 -119
  26. data/bin/console +0 -14
  27. data/bin/setup +0 -8
  28. data/example-usage.rb +0 -766
  29. data/examples/highlevel/decrypt_mem.rb +0 -44
  30. data/examples/highlevel/encrypt_mem.rb +0 -46
  31. data/examples/lowlevel/decrypt_file.rb +0 -76
  32. data/examples/lowlevel/decrypt_mem.rb +0 -80
  33. data/examples/lowlevel/encrypt_file.rb +0 -68
  34. data/examples/lowlevel/encrypt_mem.rb +0 -75
  35. data/examples/lowlevel/load_pubkey.rb +0 -118
  36. data/examples/lowlevel/print_keyring_file.rb +0 -68
  37. data/examples/lowlevel/print_keyring_mem.rb +0 -96
  38. data/examples/lowlevel/sign_file.rb +0 -104
  39. data/examples/lowlevel/sign_mem.rb +0 -96
  40. data/examples/lowlevel/verify_file.rb +0 -55
  41. data/examples/lowlevel/verify_mem.rb +0 -61
  42. data/lib/rnp/highlevel.rb +0 -5
  43. data/lib/rnp/highlevel/constants.rb +0 -96
  44. data/lib/rnp/highlevel/keyring.rb +0 -259
  45. data/lib/rnp/highlevel/publickey.rb +0 -150
  46. data/lib/rnp/highlevel/secretkey.rb +0 -318
  47. data/lib/rnp/highlevel/utils.rb +0 -119
  48. data/lib/rnp/lowlevel.rb +0 -6
  49. data/lib/rnp/lowlevel/constants.rb +0 -11
  50. data/lib/rnp/lowlevel/dynarray.rb +0 -129
  51. data/lib/rnp/lowlevel/enums.rb +0 -243
  52. data/lib/rnp/lowlevel/libc.rb +0 -28
  53. data/lib/rnp/lowlevel/libopenssl.rb +0 -15
  54. data/lib/rnp/lowlevel/librnp.rb +0 -213
  55. data/lib/rnp/lowlevel/structs.rb +0 -541
  56. data/lib/rnp/lowlevel/utils.rb +0 -25
  57. data/rnp.gemspec +0 -35
  58. data/rnp/lib/rnp.rb +0 -5
  59. data/rnp/spec/rnp_spec.rb +0 -11
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'optparse'
3
- require 'io/console'
4
-
5
- require_relative '../../lib/rnp'
6
-
7
- options = {armored: false, keys_armored: false}
8
- parser = OptionParser.new do |opts|
9
- opts.banner = "Usage: #{$0} [options] <seckey> <passphrase>"
10
- opts.on('-k', '--keys-armored', 'Keys are ASCII armored') do
11
- options[:keys_armored] = true
12
- end
13
- opts.on('-a', '--armored', 'Input is ASCII armored') do
14
- options[:armored] = true
15
- end
16
- opts.on('-h', '--help', 'Print this help') do
17
- puts opts
18
- exit
19
- end
20
- end
21
- parser.parse!
22
-
23
- if ARGV.length != 2
24
- parser.display
25
- exit
26
- end
27
-
28
- seckey_filename = ARGV.shift
29
- passphrase = ARGV.shift + "\n"
30
-
31
- secring = RNP::load_keyring(File.binread(seckey_filename), options[:keys_armored])
32
-
33
- $stdin.binmode
34
- data = $stdin.read
35
-
36
- seckey = secring[0]
37
- decrypted_data = seckey.decrypt(data, passphrase, options[:armored])
38
- if decrypted_data
39
- $stderr.puts 'Decryption succeeded'
40
- $stdout.puts decrypted_data
41
- else
42
- $stderr.puts 'Decryption failed!'
43
- end
44
-
@@ -1,46 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'optparse'
3
-
4
- require_relative '../../lib/rnp'
5
-
6
- options = {armored: false, keys_armored: false}
7
- parser = OptionParser.new do |opts|
8
- opts.banner = "Usage: #{$0} [options] <pubkey>"
9
- opts.on('-k', '--keys-armored', 'Seckey is ASCII armored') do
10
- options[:keys_armored] = true
11
- end
12
- opts.on('-a', '--armored', 'Output will be ASCII armored') do
13
- options[:armored] = true
14
- end
15
- opts.on('-h', '--help', 'Print this help') do
16
- puts opts
17
- exit
18
- end
19
- end
20
- parser.parse!
21
-
22
- if ARGV.length != 1
23
- parser.display
24
- exit
25
- end
26
-
27
- pubkey_filename = ARGV.shift
28
-
29
- keyring = RNP::load_keyring(File.binread(pubkey_filename), options[:keys_armored])
30
-
31
- pubkey = keyring[0]
32
-
33
- $stdin.binmode
34
- data = $stdin.read
35
-
36
- encrypted_data = pubkey.encrypt(data, options[:armored])
37
-
38
- $stdout.binmode
39
- $stdout.puts encrypted_data
40
-
41
- if encrypted_data != nil
42
- $stderr.puts 'Encryption succeeded'
43
- else
44
- $stderr.puts 'Encryption failed!'
45
- end
46
-
@@ -1,76 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'optparse'
3
- require 'io/console'
4
-
5
- require_relative '../../lib/rnp'
6
-
7
- options = {armored: false, keys_armored: false}
8
- parser = OptionParser.new do |opts|
9
- opts.banner = "Usage: #{$0} [options] <pubkey> <seckey> <input-file> <output-file>"
10
- opts.on('-k', '--keys-armored', 'Keys are ASCII armored') do
11
- options[:keys_armored] = true
12
- end
13
- opts.on('-a', '--armored', 'Input file is ASCII armored') do
14
- options[:armored] = true
15
- end
16
- opts.on('-h', '--help', 'Print this help') do
17
- puts opts
18
- exit
19
- end
20
- end
21
- parser.parse!
22
-
23
- if ARGV.length != 4
24
- parser.display
25
- exit
26
- end
27
-
28
- pubkey_filename = ARGV.shift
29
- seckey_filename = ARGV.shift
30
- input_filename = ARGV.shift
31
- output_filename = ARGV.shift
32
-
33
- # Load pubkey/keyring
34
- pubkeyring_mem = LibC::calloc(1, LibRNP::PGPKeyring.size)
35
- pubkeyring = LibRNP::PGPKeyring.new(pubkeyring_mem)
36
- if 1 != LibRNP::pgp_keyring_fileread(pubkeyring, options[:keys_armored] ? 1 : 0, pubkey_filename)
37
- puts 'Errors encountered while loading public keyring.'
38
- exit 1
39
- end
40
- # Load seckey/keyring
41
- seckeyring_mem = LibC::calloc(1, LibRNP::PGPKeyring.size)
42
- seckeyring = LibRNP::PGPKeyring.new(seckeyring_mem)
43
- if 1 != LibRNP::pgp_keyring_fileread(seckeyring, options[:keys_armored] ? 1 : 0, seckey_filename)
44
- puts 'Errors encountered while loading secret keyring.'
45
- exit 1
46
- end
47
-
48
- pgpio = LibRNP::PGPIO.new
49
- stdout_fp = LibC::fdopen($stdout.to_i, 'w')
50
- stderr_fp = LibC::fdopen($stderr.to_i, 'w')
51
- pgpio[:outs] = stdout_fp
52
- pgpio[:errs] = stderr_fp
53
- pgpio[:res] = stdout_fp
54
-
55
- rd, wr = IO.pipe
56
- print 'Enter passphrase: '
57
- passphrase = $stdin.noecho(&:gets)
58
- puts ''
59
- wr.write passphrase
60
- wr.close
61
- passfp = LibC::fdopen(rd.to_i, 'r')
62
-
63
- armored = options[:armored] ? 1 : 0
64
- overwrite = 1
65
- sshkeys = 0
66
- numtries = 1
67
-
68
- ret = LibRNP::pgp_decrypt_file(pgpio, input_filename, output_filename, seckeyring, pubkeyring, armored, overwrite, sshkeys, passfp, numtries, nil)
69
- rd.close
70
- LibC::fclose(passfp)
71
- if ret == 1
72
- puts 'Success'
73
- else
74
- puts 'Failed!'
75
- end
76
-
@@ -1,80 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'optparse'
3
- require 'io/console'
4
-
5
- require_relative '../../lib/rnp'
6
-
7
- options = {armored: false, keys_armored: false}
8
- parser = OptionParser.new do |opts|
9
- opts.banner = "Usage: #{$0} [options] <pubkey> <seckey> <passphrase>"
10
- opts.on('-k', '--keys-armored', 'Keys are ASCII armored') do
11
- options[:keys_armored] = true
12
- end
13
- opts.on('-a', '--armored', 'Input is ASCII armored') do
14
- options[:armored] = true
15
- end
16
- opts.on('-h', '--help', 'Print this help') do
17
- puts opts
18
- exit
19
- end
20
- end
21
- parser.parse!
22
-
23
- if ARGV.length != 3
24
- parser.display
25
- exit
26
- end
27
-
28
- pubkey_filename = ARGV.shift
29
- seckey_filename = ARGV.shift
30
- passphrase = ARGV.shift + "\n"
31
-
32
- # Load pubkey/keyring
33
- pubkeyring_mem = LibC::calloc(1, LibRNP::PGPKeyring.size)
34
- pubkeyring = LibRNP::PGPKeyring.new(pubkeyring_mem)
35
- if 1 != LibRNP::pgp_keyring_fileread(pubkeyring, options[:keys_armored] ? 1 : 0, pubkey_filename)
36
- puts 'Errors encountered while loading public keyring.'
37
- exit 1
38
- end
39
- # Load seckey/keyring
40
- seckeyring_mem = LibC::calloc(1, LibRNP::PGPKeyring.size)
41
- seckeyring = LibRNP::PGPKeyring.new(seckeyring_mem)
42
- if 1 != LibRNP::pgp_keyring_fileread(seckeyring, options[:keys_armored] ? 1 : 0, seckey_filename)
43
- puts 'Errors encountered while loading secret keyring.'
44
- exit 1
45
- end
46
-
47
- pgpio = LibRNP::PGPIO.new
48
- stderr_fp = LibC::fdopen($stderr.to_i, 'w')
49
- # send all to stderr
50
- pgpio[:outs] = stderr_fp
51
- pgpio[:errs] = stderr_fp
52
- pgpio[:res] = stderr_fp
53
-
54
- rd, wr = IO.pipe
55
- wr.write passphrase
56
- wr.close
57
- passfp = LibC::fdopen(rd.to_i, 'r')
58
-
59
- armored = options[:armored] ? 1 : 0
60
- sshkeys = 0
61
- numtries = 1
62
-
63
- $stdin.binmode
64
- data = $stdin.read
65
- data_buf = FFI::MemoryPointer.new(:uint8, data.bytesize)
66
- data_buf.put_bytes(0, data)
67
- memory_ptr = LibRNP::pgp_decrypt_buf(pgpio, data_buf, data_buf.size, seckeyring, pubkeyring, armored, sshkeys, passfp, numtries, nil)
68
- rd.close
69
- LibC::fclose(passfp)
70
-
71
- memory = LibRNP::PGPMemory.new(memory_ptr)
72
- if not memory.null?
73
- $stdout.binmode
74
- $stdout.puts memory[:buf].read_bytes(memory[:length])
75
- LibRNP::pgp_memory_free(memory)
76
- $stderr.puts 'Success'
77
- else
78
- $stderr.puts 'Failed!'
79
- end
80
-
@@ -1,68 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'optparse'
3
-
4
- require_relative '../../lib/rnp'
5
-
6
- options = {armored: false, keys_armored: false}
7
- parser = OptionParser.new do |opts|
8
- opts.banner = "Usage: #{$0} [options] <pubkey> <input-file> <output-file>"
9
- opts.on('-k', '--keys-armored', 'Seckey is ASCII armored') do
10
- options[:keys_armored] = true
11
- end
12
- opts.on('-a', '--armored', 'Output file will be ASCII armored') do
13
- options[:armored] = true
14
- end
15
- opts.on('-h', '--help', 'Print this help') do
16
- puts opts
17
- exit
18
- end
19
- end
20
- parser.parse!
21
-
22
- if ARGV.length != 3
23
- parser.display
24
- exit
25
- end
26
-
27
- pubkey_filename = ARGV.shift
28
- input_filename = ARGV.shift
29
- output_filename = ARGV.shift
30
-
31
- # Load keys/keyring
32
- keyring_mem = LibC::calloc(1, LibRNP::PGPKeyring.size)
33
- keyring = LibRNP::PGPKeyring.new(keyring_mem)
34
- if 1 != LibRNP::pgp_keyring_fileread(keyring, options[:keys_armored] ? 1 : 0, pubkey_filename)
35
- puts 'Errors encountered while loading keyring.'
36
- exit 1
37
- end
38
- # Find first pubkey
39
- keycount = LibRNP::dynarray_count(keyring, 'key')
40
- pubkey = nil
41
- (0..keycount - 1).each {|keyn|
42
- key = LibRNP::dynarray_get_item(keyring, 'key', LibRNP::PGPKey, keyn)
43
- pubkey = key if LibRNP::pgp_is_key_secret(key) == 0
44
- break if pubkey != nil
45
- }
46
- if pubkey == nil
47
- puts 'No pubkey found'
48
- exit 1
49
- end
50
-
51
- pgpio = LibRNP::PGPIO.new
52
- stdout_fp = LibC::fdopen($stdout.to_i, 'w')
53
- stderr_fp = LibC::fdopen($stderr.to_i, 'w')
54
- pgpio[:outs] = stdout_fp
55
- pgpio[:errs] = stderr_fp
56
- pgpio[:res] = stdout_fp
57
-
58
- armored = options[:armored] ? 1 : 0
59
- overwrite = 1
60
- # see pgp_str_to_cipher
61
- cipher = 'cast5'
62
- ret = LibRNP::pgp_encrypt_file(pgpio, input_filename, output_filename, pubkey, armored, overwrite, cipher)
63
- if ret == 1
64
- puts 'Success'
65
- else
66
- puts 'Failed!'
67
- end
68
-
@@ -1,75 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require 'optparse'
3
-
4
- require_relative '../../lib/rnp'
5
-
6
- options = {armored: false, keys_armored: false}
7
- parser = OptionParser.new do |opts|
8
- opts.banner = "Usage: #{$0} [options] <pubkey>"
9
- opts.on('-k', '--keys-armored', 'Seckey is ASCII armored') do
10
- options[:keys_armored] = true
11
- end
12
- opts.on('-a', '--armored', 'Output will be ASCII armored') do
13
- options[:armored] = true
14
- end
15
- opts.on('-h', '--help', 'Print this help') do
16
- puts opts
17
- exit
18
- end
19
- end
20
- parser.parse!
21
-
22
- if ARGV.length != 1
23
- parser.display
24
- exit
25
- end
26
-
27
- pubkey_filename = ARGV.shift
28
-
29
- # Load keys/keyring
30
- keyring_mem = LibC::calloc(1, LibRNP::PGPKeyring.size)
31
- keyring = LibRNP::PGPKeyring.new(keyring_mem)
32
- if 1 != LibRNP::pgp_keyring_fileread(keyring, options[:keys_armored] ? 1 : 0, pubkey_filename)
33
- puts 'Errors encountered while loading keyring.'
34
- exit 1
35
- end
36
- # Find first pubkey
37
- keycount = LibRNP::dynarray_count(keyring, 'key')
38
- pubkey = nil
39
- (0..keycount - 1).each {|keyn|
40
- key = LibRNP::dynarray_get_item(keyring, 'key', LibRNP::PGPKey, keyn)
41
- pubkey = key if LibRNP::pgp_is_key_secret(key) == 0
42
- break if pubkey != nil
43
- }
44
- if pubkey == nil
45
- puts 'No pubkey found'
46
- exit 1
47
- end
48
-
49
- pgpio = LibRNP::PGPIO.new
50
- stdout_fp = LibC::fdopen($stdout.to_i, 'w')
51
- stderr_fp = LibC::fdopen($stderr.to_i, 'w')
52
- pgpio[:outs] = stdout_fp
53
- pgpio[:errs] = stderr_fp
54
- pgpio[:res] = stdout_fp
55
-
56
- armored = options[:armored] ? 1 : 0
57
- # see pgp_str_to_cipher
58
- cipher = 'cast5'
59
- $stdin.binmode
60
- data = $stdin.read
61
- data_buf = FFI::MemoryPointer.new(:uint8, data.bytesize)
62
- data_buf.put_bytes(0, data)
63
- memory_ptr = LibRNP::pgp_encrypt_buf(pgpio, data_buf, data_buf.size, pubkey, armored, cipher)
64
-
65
- memory = LibRNP::PGPMemory.new(memory_ptr)
66
- $stdout.binmode
67
- $stdout.puts memory[:buf].read_bytes(memory[:length])
68
- LibRNP::pgp_memory_free(memory)
69
-
70
- if not memory.null?
71
- $stderr.puts 'Success'
72
- else
73
- $stderr.puts 'Failed!'
74
- end
75
-
@@ -1,118 +0,0 @@
1
- #!/usr/bin/env ruby
2
- require_relative '../../lib/rnp'
3
-
4
- def bignum_byte_count(bn)
5
- bn.to_s(16).length / 2
6
- end
7
-
8
- class PublicKey
9
- attr_accessor :version,
10
- :creation_time,
11
- :expiration_time,
12
- :public_key_algorithm,
13
- :mpi,
14
- :userids
15
-
16
- def initialize
17
- @version = nil
18
- @creation_time = nil
19
- @expiration_time = nil
20
- @public_key_algorithm = nil
21
- @mpi = {}
22
-
23
- @userids = []
24
- end
25
-
26
- def bitcount
27
- case @public_key_algorithm
28
- when :PGP_PKA_RSA, :PGP_PKA_RSA_ENCRYPT_ONLY, :PGP_PKA_RSA_SIGN_ONLY
29
- return RNP::bignum_byte_count(@n) * 8
30
- when :PGP_PKA_DSA
31
- case RNP::bignum_byte_count(@q)
32
- when 20
33
- 1024
34
- when 28
35
- 2048
36
- when 32
37
- 3072
38
- end
39
- when :PGP_PKA_ELGAMAL
40
- RNP::bignum_byte_count(@y) * 8
41
- end
42
- 0
43
- end
44
-
45
- end
46
-
47
- PARSE_PUBLIC_KEY = Proc.new do |results, pkt, data|
48
- case pkt[:tag]
49
- when :PGP_PARSER_PTAG
50
-
51
- when :PGP_PARSER_PACKET_END
52
- when :PGP_PTAG_CT_PUBLIC_KEY, :PGP_PTAG_CT_PUBLIC_SUBKEY
53
- pk = pkt[:u][:pubkey]
54
- pubkey = PublicKey.new
55
- case pk[:alg]
56
- when :PGP_PKA_RSA, :PGP_PKA_RSA_ENCRYPT_ONLY, :PGP_PKA_RSA_SIGN_ONLY
57
- rsa = pk[:key][:rsa]
58
- pubkey.mpi[:n] = LibRNP::bn2hex(rsa[:n]).hex
59
- pubkey.mpi[:e] = LibRNP::bn2hex(rsa[:e]).hex
60
- when :PGP_PKA_DSA
61
- dsa = pk[:key][:dsa]
62
- pubkey.mpi[:p] = LibRNP::bn2hex(dsa[:p]).hex
63
- pubkey.mpi[:q] = LibRNP::bn2hex(dsa[:q]).hex
64
- pubkey.mpi[:g] = LibRNP::bn2hex(dsa[:g]).hex
65
- pubkey.mpi[:y] = LibRNP::bn2hex(dsa[:y]).hex
66
- when :PGP_PKA_ELGAMAL
67
- elg = pk[:key][:elgamal]
68
- pubkey.mpi[:p] = LibRNP::bn2hex(rsa[:p]).hex
69
- pubkey.mpi[:g] = LibRNP::bn2hex(rsa[:g]).hex
70
- pubkey.mpi[:y] = LibRNP::bn2hex(rsa[:y]).hex
71
- else
72
- next :PGP_RELEASE_MEMORY
73
- end
74
- pubkey.version = pk[:version]
75
- pubkey.creation_time = Time.at(pk[:birthtime])
76
- pubkey.public_key_algorithm = pk[:alg]
77
- results.push(pubkey)
78
- when :PGP_PTAG_SS_KEY_EXPIRY
79
- pubkey = results.last
80
- pubkey.expiration_time = Time.at(results.last.creation_time.to_i + pkt[:u][:ss_time])
81
- when :PGP_PTAG_CT_USER_ID
82
- pubkey = results.last
83
- pubkey.userids.push(pkt[:u][:userid].force_encoding('utf-8'))
84
- end
85
- next :PGP_RELEASE_MEMORY
86
- end
87
-
88
- def load_pubkey(data, armored=false, print_errors=true)
89
- stream_mem = LibC::calloc(1, LibRNP::PGPStream.size)
90
- # This will free the above memory (PGPStream is a ManagedStruct)
91
- stream = LibRNP::PGPStream.new(stream_mem)
92
- stream[:readinfo][:accumulate] = 1
93
- LibRNP::pgp_parse_options(stream, :PGP_PTAG_SS_ALL, :PGP_PARSE_PARSED)
94
-
95
- # This memory will be GC'd
96
- mem = FFI::MemoryPointer.new(:uint8, data.bytesize)
97
- mem.put_bytes(0, data)
98
-
99
- LibRNP::pgp_reader_set_memory(stream, mem, mem.size)
100
- results = []
101
- callback = PARSE_PUBLIC_KEY.curry[results]
102
- LibRNP::pgp_set_callback(stream, callback, nil)
103
- LibRNP::pgp_reader_push_dearmour(stream) if armored
104
- LibRNP::pgp_parse(stream, print_errors ? 1 : 0)
105
- LibRNP::pgp_reader_pop_dearmour(stream) if armored
106
- results[0]
107
- end
108
-
109
- def usage
110
- puts "Usage: #{$0} <file>"
111
- exit 1
112
- end
113
-
114
- usage if ARGV.length != 1
115
- armored = ARGV[0].downcase.end_with?('.asc')
116
- pubkey = load_pubkey(File.binread(ARGV[0]), armored)
117
- puts pubkey.inspect
118
-