module NetPGP
Constants
- DEFAULT_PASSPHRASE_PROVIDER
- PARSE_KEYRING
Public Class Methods
add_subkey_signature(key, subkey)
click to toggle source
Add a subkey binding signature (type 0x18) to a key. Note that this should be used for encryption subkeys.
@param key [LibNetPGP::PGPKey] @param subkey [LibNetPGP::PGPKey]
# 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') # TODO expiration 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)
click to toggle source
# File lib/netpgp/highlevel/utils.rb, line 3 def self.bignum_byte_count(bn) # Note: This probably assumes that the ruby implementation # uses the same BN representation that libnetpgp does. # It may be better to convert and use BN_num_bytes (or bits). bn.to_s(16).length / 2 end
keys_to_native_keyring(keys, native)
click to toggle source
# 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)
click to toggle source
# File lib/netpgp/highlevel/keyring.rb, line 191 def self.load_keys(data, armored=true, &passphrase_provider) # Just for readability print_errors = 0 stream_mem = LibC::calloc(1, LibNetPGP::PGPStream.size) # This will free the above memory (PGPStream is a ManagedStruct) stream = LibNetPGP::PGPStream.new(stream_mem) stream[:readinfo][:accumulate] = 1 LibNetPGP::pgp_parse_options(stream, :PGP_PTAG_SS_ALL, :PGP_PARSE_PARSED) # This memory will be GC'd 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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)
click to toggle source
# 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 # Ensure we're not leaking memory from a prior call. # This just frees all the BNs. 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)
click to toggle source
# 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)
click to toggle source
# 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) # pgp_validate_mem frees this mem_ptr = LibC::calloc(1, LibNetPGP::PGPMemory.size) mem = LibNetPGP::PGPMemory.new(mem_ptr) LibNetPGP::pgp_memory_add(mem, data_buf, data_buf.size) # ManagedStruct, this frees itself 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