32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
# File 'lib/netpgp/highlevel/keyring.rb', line 32
def export(key, armored=true)
raise if key.parent
is_public = key.is_a?(PublicKey)
if is_public
seckey = secret_keys.find {|sk| sk.key_id == key.key_id}
else
seckey = key
end
return nil if not seckey
output_ptr = FFI::MemoryPointer.new(:pointer)
mem_ptr = FFI::MemoryPointer.new(:pointer)
output = nil
mem = nil
decrypted_seckey = nil
begin
LibNetPGP::pgp_setup_memory_write(output_ptr, mem_ptr, 4096)
output = LibNetPGP::PGPOutput.new(output_ptr.read_pointer)
mem = LibNetPGP::PGPMemory.new(mem_ptr.read_pointer)
native_ptr = LibC::calloc(1, LibNetPGP::PGPKey.size)
native = LibNetPGP::PGPKey.new(native_ptr)
native_auto = FFI::AutoPointer.new(native_ptr, LibNetPGP::PGPKey.method(:release))
key.to_native_key(native)
decrypted_seckey = seckey.decrypted_seckey
return nil if not decrypted_seckey
seckey = SecretKey.from_native(decrypted_seckey)
seckey.to_native(native[:key][:seckey])
native[:type] = :PGP_PTAG_CT_SECRET_KEY
if is_public
LibNetPGP::dynarray_clear(native, 'uid', :string)
key.userids.each {|userid|
LibNetPGP::pgp_add_selfsigned_userid(native, userid)
}
end
subkeysring_ptr = LibC::calloc(1, LibNetPGP::PGPKeyring.size)
subkeysring = LibNetPGP::PGPKeyring.new(subkeysring_ptr)
NetPGP::keys_to_native_keyring(key.subkeys, subkeysring)
(0..LibNetPGP::dynarray_count(subkeysring, 'key') - 1).each {|n|
subkey = LibNetPGP::dynarray_get_item(subkeysring, 'key', LibNetPGP::PGPKey, n)
LibNetPGP::dynarray_clear(subkey, 'packet', LibNetPGP::PGPSubPacket)
NetPGP::add_subkey_signature(native, subkey)
}
if is_public
ret = LibNetPGP::pgp_write_xfer_pubkey(output, native, subkeysring, armored ? 1 : 0)
else
decrypted_key_ptr = LibC::calloc(1, LibNetPGP::PGPKey.size)
decrypted_key = LibNetPGP::PGPKey.new(decrypted_key_ptr)
decrypted_key_auto = FFI::AutoPointer.new(decrypted_key_ptr, LibNetPGP::PGPKey.method(:release))
seckey.to_native_key(decrypted_key)
key.userids.each {|userid|
LibNetPGP::pgp_add_selfsigned_userid(decrypted_key, userid)
}
decrypted_key[:key][:seckey][:s2k_usage] = :PGP_S2KU_ENCRYPTED_AND_HASHED
decrypted_key[:key][:seckey][:alg] = :PGP_SA_CAST5
decrypted_key[:key][:seckey][:s2k_specifier] = :PGP_S2KS_SALTED
(0..LibNetPGP::dynarray_count(subkeysring, 'key') - 1).each {|n|
subkey = LibNetPGP::dynarray_get_item(subkeysring, 'key', LibNetPGP::PGPKey, n)
subkey[:key][:seckey][:s2k_usage] = :PGP_S2KU_ENCRYPTED_AND_HASHED
subkey[:key][:seckey][:alg] = :PGP_SA_CAST5
subkey[:key][:seckey][:s2k_specifier] = :PGP_S2KS_SALTED
}
ret = LibNetPGP::pgp_write_xfer_seckey(output, decrypted_key, key.passphrase, key.passphrase.size, subkeysring, armored ? 1 : 0)
end
return nil if ret != 1
data = mem[:buf].read_bytes(mem[:length])
data
ensure
LibNetPGP::pgp_teardown_memory_write(output, mem) if mem
LibNetPGP::pgp_seckey_free(decrypted_seckey) if decrypted_seckey
end
end
|