rnp 0.2.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
-