Module: NetPGP
- Defined in:
- lib/netpgp/highlevel/utils.rb,
lib/netpgp/highlevel/keyring.rb,
lib/netpgp/highlevel/constants.rb,
lib/netpgp/highlevel/publickey.rb,
lib/netpgp/highlevel/secretkey.rb
Defined Under Namespace
Classes: HashAlgorithm, Keyring, PublicKey, PublicKeyAlgorithm, SecretKey, StringToKeySpecifier, StringToKeyUsage, SymmetricKeyAlgorithm
Constant Summary
collapse
- PARSE_KEYRING =
Proc.new do |state, passphrase_provider, pkt, data|
next :PGP_RELEASE_MEMORY if state[:errors].any?
begin
lastkey = state[:keys].last
case pkt[:tag]
when :PGP_PTAG_CT_PUBLIC_KEY
key = PublicKey::from_native(pkt[:u][:pubkey])
state[:keys].push(key)
when :PGP_PTAG_CT_PUBLIC_SUBKEY
key = PublicKey::from_native(pkt[:u][:pubkey])
lastkey.add_subkey(key)
state[:keys].push(key)
when :PGP_PTAG_CT_ENCRYPTED_SECRET_KEY
key = SecretKey::from_native(pkt[:u][:seckey], true)
state[:keys].push(key)
when :PGP_PTAG_CT_ENCRYPTED_SECRET_SUBKEY
key = SecretKey::from_native(pkt[:u][:seckey], true)
lastkey.add_subkey(key)
state[:keys].push(key)
when :PGP_PTAG_CT_SECRET_KEY
key = SecretKey::from_native(pkt[:u][:seckey])
if state[:passphrase]
key.passphrase = state[:passphrase]
state[:passphrase] = nil
end
state[:keys].push(key)
when :PGP_PTAG_CT_SECRET_SUBKEY
key = SecretKey::from_native(pkt[:u][:seckey])
lastkey.add_subkey(key)
state[:keys].push(key)
when :PGP_GET_PASSPHRASE
seckey_ptr = pkt[:u][:skey_passphrase][:seckey]
seckey = LibNetPGP::PGPSecKey.new(seckey_ptr)
key = SecretKey::from_native(seckey)
passphrase = passphrase_provider.call(key)
if passphrase and passphrase != ''
passphrase_mem = LibC::calloc(1, passphrase.bytesize + 1)
passphrase_mem.write_bytes(passphrase)
pkt[:u][:skey_passphrase][:passphrase].write_pointer(passphrase_mem)
state[:passphrase] = passphrase
next :PGP_KEEP_MEMORY
end
when :PGP_PARSER_PACKET_END
if lastkey.is_a? NetPGP::SecretKey
raw_packet = pkt[:u][:packet]
bytes = raw_packet[:raw].read_bytes(raw_packet[:length])
lastkey.raw_subpackets.push(bytes)
end
when :PGP_PTAG_CT_USER_ID
lastkey.userids.push(pkt[:u][:userid].force_encoding('utf-8'))
when :PGP_PTAG_SS_KEY_EXPIRY
lastkey.expiration_time = lastkey.creation_time + pkt[:u][:ss_time]
else
end rescue
state[:errors].push($ERROR_INFO)
end
next :PGP_RELEASE_MEMORY
end
- DEFAULT_PASSPHRASE_PROVIDER =
Proc.new do |seckey|
nil
end
Class Method Summary
collapse
-
.add_subkey_signature(key, subkey) ⇒ Object
Add a subkey binding signature (type 0x18) to a key.
-
.bignum_byte_count(bn) ⇒ Object
-
.keys_to_native_keyring(keys, native) ⇒ Object
-
.load_keys(data, armored = true, &passphrase_provider) ⇒ Object
-
.mpi_from_native(native) ⇒ Object
-
.mpi_to_native(mpi, native) ⇒ Object
-
.mpis_from_native(alg, native) ⇒ Object
-
.mpis_to_native(alg, mpi, native) ⇒ Object
-
.stream_errors(stream) ⇒ Object
-
.verify(keys, data, armored = true) ⇒ Object
Class Method Details
.add_subkey_signature(key, subkey) ⇒ Object
Add a subkey binding signature (type 0x18) to a key. Note that this should be used for encryption subkeys.
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
# File 'lib/netpgp/highlevel/utils.rb', line 90
def self.add_subkey_signature(key, subkey)
sig = nil
sigoutput = nil
mem_sig = nil
begin
sig = LibNetPGP::pgp_create_sig_new
LibNetPGP::pgp_sig_start_subkey_sig(sig, key[:key][:pubkey], subkey[:key][:pubkey], :PGP_SIG_SUBKEY)
LibNetPGP::pgp_add_time(sig, subkey[:key][:pubkey][:birthtime], 'birth')
LibNetPGP::pgp_add_issuer_keyid(sig, key[:sigid])
LibNetPGP::pgp_end_hashed_subpkts(sig)
sigoutput_ptr = FFI::MemoryPointer.new(:pointer)
mem_sig_ptr = FFI::MemoryPointer.new(:pointer)
LibNetPGP::pgp_setup_memory_write(sigoutput_ptr, mem_sig_ptr, 128)
sigoutput = LibNetPGP::PGPOutput.new(sigoutput_ptr.read_pointer)
LibNetPGP::pgp_write_sig(sigoutput, sig, key[:key][:pubkey], key[:key][:seckey])
mem_sig = LibNetPGP::PGPMemory.new(mem_sig_ptr.read_pointer)
sigpkt = LibNetPGP::PGPSubPacket.new
sigpkt[:length] = LibNetPGP::pgp_mem_len(mem_sig)
sigpkt[:raw] = LibNetPGP::pgp_mem_data(mem_sig)
LibNetPGP::pgp_add_subpacket(subkey, sigpkt)
ensure
LibNetPGP::pgp_create_sig_delete(sig) if sig
LibNetPGP::pgp_teardown_memory_write(sigoutput, mem_sig) if mem_sig
end
end
|
.bignum_byte_count(bn) ⇒ Object
3
4
5
6
7
8
|
# File 'lib/netpgp/highlevel/utils.rb', line 3
def self.bignum_byte_count(bn)
bn.to_s(16).length / 2
end
|
.keys_to_native_keyring(keys, native) ⇒ Object
222
223
224
225
226
227
228
229
230
|
# File 'lib/netpgp/highlevel/keyring.rb', line 222
def self.keys_to_native_keyring(keys, native)
raise if not native[:keys].null?
for key in keys
native_key = LibNetPGP::PGPKey.new
key.to_native_key(native_key)
LibNetPGP::dynarray_append_item(native, 'key', LibNetPGP::PGPKey, native_key)
end
end
|
.load_keys(data, armored = true, &passphrase_provider) ⇒ Object
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
|
# File 'lib/netpgp/highlevel/keyring.rb', line 191
def self.load_keys(data, armored=true, &passphrase_provider)
print_errors = 0
stream_mem = LibC::calloc(1, LibNetPGP::PGPStream.size)
stream = LibNetPGP::PGPStream.new(stream_mem)
stream[:readinfo][:accumulate] = 1
LibNetPGP::pgp_parse_options(stream, :PGP_PTAG_SS_ALL, :PGP_PARSE_PARSED)
mem = FFI::MemoryPointer.new(:uint8, data.bytesize)
mem.write_bytes(data)
LibNetPGP::pgp_reader_set_memory(stream, mem, mem.size)
state = {keys: [], errors: []}
provider = block_given? ? passphrase_provider : DEFAULT_PASSPHRASE_PROVIDER
callback = NetPGP::PARSE_KEYRING.curry[state][provider]
LibNetPGP::pgp_set_callback(stream, callback, nil)
LibNetPGP::pgp_reader_push_dearmour(stream) if armored
if LibNetPGP::pgp_parse(stream, print_errors) != 1
state[:errors].push('pgp_parse failed')
end
LibNetPGP::pgp_reader_pop_dearmour(stream) if armored
errors = stream_errors(stream)
state[:errors].push(errors) if errors.any?
raise state[:errors].join("\n") if state[:errors].any?
state[:keys]
end
|
.mpi_from_native(native) ⇒ Object
25
26
27
28
29
30
31
32
33
34
35
|
# File 'lib/netpgp/highlevel/utils.rb', line 25
def self.mpi_from_native(native)
mpi = {}
native.members.each {|member|
if native[member].null?
mpi[member] = nil
else
mpi[member] = LibNetPGP::bn2hex(native[member]).hex
end
}
mpi
end
|
.mpi_to_native(mpi, native) ⇒ Object
51
52
53
54
55
56
57
58
59
|
# File 'lib/netpgp/highlevel/utils.rb', line 51
def self.mpi_to_native(mpi, native)
mpi.each {|name,value|
if mpi[name] == nil
native[name] = nil
else
native[name] = LibNetPGP::num2bn(value)
end
}
end
|
.mpis_from_native(alg, native) ⇒ Object
37
38
39
40
41
42
43
44
45
46
47
48
49
|
# File 'lib/netpgp/highlevel/utils.rb', line 37
def self.mpis_from_native(alg, native)
case alg
when :PGP_PKA_RSA, :PGP_PKA_RSA_ENCRYPT_ONLY, :PGP_PKA_RSA_SIGN_ONLY
material = native[:key][:rsa]
when :PGP_PKA_DSA
material = native[:key][:dsa]
when :PGP_PKA_ELGAMAL
material = native[:key][:elgamal]
else
raise "Unsupported PK algorithm: #{alg}"
end
NetPGP::mpi_from_native(material)
end
|
.mpis_to_native(alg, mpi, native) ⇒ Object
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
# File 'lib/netpgp/highlevel/utils.rb', line 61
def self.mpis_to_native(alg, mpi, native)
case alg
when :PGP_PKA_RSA, :PGP_PKA_RSA_ENCRYPT_ONLY, :PGP_PKA_RSA_SIGN_ONLY
material = native[:key][:rsa]
when :PGP_PKA_DSA
material = native[:key][:dsa]
when :PGP_PKA_ELGAMAL
material = native[:key][:elgamal]
else
raise "Unsupported PK algorithm: #{alg}"
end
if native.is_a?(LibNetPGP::PGPSecKey)
LibNetPGP::pgp_seckey_free(native)
elsif native.is_a?(LibNetPGP::PGPPubKey)
LibNetPGP::pgp_pubkey_free(native)
else
raise
end
NetPGP::mpi_to_native(mpi, material)
end
|
.stream_errors(stream) ⇒ Object
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
# File 'lib/netpgp/highlevel/utils.rb', line 10
def self.stream_errors(stream)
error_ptr = stream[:errors]
errors = []
until error_ptr.null?
error = LibNetPGP::PGPError.new(error_ptr)
error_desc = "#{error[:file]}:#{error[:line]}: #{error[:errcode]} #{error[:comment]}"
errors.push(error_desc)
error_ptr = error[:next]
end
errors
end
|
.verify(keys, data, armored = true) ⇒ Object
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
|
# File 'lib/netpgp/highlevel/keyring.rb', line 232
def self.verify(keys, data, armored=true)
native_keyring_ptr = LibC::calloc(1, LibNetPGP::PGPKeyring.size)
native_keyring = LibNetPGP::PGPKeyring.new(native_keyring_ptr)
NetPGP::keys_to_native_keyring(keys, native_keyring)
pgpio = LibNetPGP::PGPIO.new
pgpio[:outs] = LibC::fdopen($stdout.to_i, 'w')
pgpio[:errs] = LibC::fdopen($stderr.to_i, 'w')
pgpio[:res] = pgpio[:errs]
data_buf = FFI::MemoryPointer.new(:uint8, data.bytesize)
data_buf.write_bytes(data)
mem_ptr = LibC::calloc(1, LibNetPGP::PGPMemory.size)
mem = LibNetPGP::PGPMemory.new(mem_ptr)
LibNetPGP::pgp_memory_add(mem, data_buf, data_buf.size)
result_ptr = LibC::calloc(1, LibNetPGP::PGPValidation.size)
result = LibNetPGP::PGPValidation.new(result_ptr)
ret = LibNetPGP::pgp_validate_mem(pgpio, result, mem, nil, armored ? 1 : 0, native_keyring)
ret == 1
end
|