module HrrRbSsh::Transport::KexAlgorithm::DiffieHellmanGroupExchange

Public Class Methods

new(logger: nil) click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 16
def initialize logger: nil
  self.logger = logger
end

Public Instance Methods

hash(transport) click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 79
def hash transport
  h0_payload = {
    :'V_C' => transport.v_c,
    :'V_S' => transport.v_s,
    :'I_C' => transport.i_c,
    :'I_S' => transport.i_s,
    :'K_S' => @k_s,
    :'min' => @min,
    :'n'   => @n,
    :'max' => @max,
    :'p'   => @p,
    :'g'   => @g,
    :'e'   => @e,
    :'f'   => @f,
    :'k'   => @shared_secret,
  }
  h0 = H0.new(logger: logger).encode h0_payload
  h = OpenSSL::Digest.digest self.class::DIGEST, h0
end
initialize_dh(pg=nil) click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 55
def initialize_dh pg=nil
  unless pg
    p_list = KexAlgorithm.list_supported.map{ |e| KexAlgorithm[e] }.select{ |e| e.const_defined?(:P) }.map{ |e| [OpenSSL::BN.new(e::P,16).num_bits, e::P] }.sort_by{ |e| e[0] }.reverse
    candidate = p_list.find{ |e| e[0] <= @n }
    raise unless (@min .. @max).include?(candidate[0])
    p, g = candidate[1], 2
  else
    p, g = pg
  end
  @dh = OpenSSL::PKey::DH.new
  if @dh.respond_to?(:set_pqg)
    @dh.set_pqg OpenSSL::BN.new(p, 16), nil, OpenSSL::BN.new(g)
  else
    @dh.p = OpenSSL::BN.new(p, 16)
    @dh.g = OpenSSL::BN.new(g)
  end
  @dh.generate_key!
  @public_key = @dh.pub_key.to_i
end
receive_kex_dh_gex_group(payload) click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 144
def receive_kex_dh_gex_group payload
  Message::SSH_MSG_KEX_DH_GEX_GROUP.new(logger: logger).decode payload
end
receive_kex_dh_gex_init(payload) click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 118
def receive_kex_dh_gex_init payload
  Message::SSH_MSG_KEX_DH_GEX_INIT.new(logger: logger).decode payload
end
receive_kex_dh_gex_reply(payload) click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 157
def receive_kex_dh_gex_reply payload
  Message::SSH_MSG_KEX_DH_GEX_REPLY.new(logger: logger).decode payload
end
receive_kex_dh_gex_request(payload) click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 104
def receive_kex_dh_gex_request payload
  Message::SSH_MSG_KEX_DH_GEX_REQUEST.new(logger: logger).decode payload
end
send_kex_dh_gex_group(transport) click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 108
def send_kex_dh_gex_group transport
  message = {
    :'message number' => Message::SSH_MSG_KEX_DH_GEX_GROUP::VALUE,
    :'p'              => @p,
    :'g'              => @g,
  }
  payload = Message::SSH_MSG_KEX_DH_GEX_GROUP.new(logger: logger).encode message
  transport.send payload
end
send_kex_dh_gex_init(transport) click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 148
def send_kex_dh_gex_init transport
  message = {
    :'message number' => Message::SSH_MSG_KEX_DH_GEX_INIT::VALUE,
    :'e'              => @e,
  }
  payload = Message::SSH_MSG_KEX_DH_GEX_INIT.new(logger: logger).encode message
  transport.send payload
end
send_kex_dh_gex_reply(transport) click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 122
def send_kex_dh_gex_reply transport
  message = {
    :'message number'                                => Message::SSH_MSG_KEX_DH_GEX_REPLY::VALUE,
    :'server public host key and certificates (K_S)' => @k_s,
    :'f'                                             => @f,
    :'signature of H'                                => sign(transport),
  }
  payload = Message::SSH_MSG_KEX_DH_GEX_REPLY.new(logger: logger).encode message
  transport.send payload
end
send_kex_dh_gex_request(transport) click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 133
def send_kex_dh_gex_request transport
  message = {
    :'message number' => Message::SSH_MSG_KEX_DH_GEX_REQUEST::VALUE,
    :'min'            => @min,
    :'n'              => @n,
    :'max'            => @max,
  }
  payload = Message::SSH_MSG_KEX_DH_GEX_REQUEST.new(logger: logger).encode message
  transport.send payload
end
shared_secret() click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 75
def shared_secret
  @shared_secret
end
sign(transport) click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 99
def sign transport
  h = hash transport
  s = transport.server_host_key_algorithm.sign h
end
start(transport) click to toggle source
# File lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb, line 20
def start transport
  case transport.mode
  when Mode::SERVER
    message = receive_kex_dh_gex_request transport.receive
    @min = message[:'min']
    @n   = message[:'n']
    @max = message[:'max']
    initialize_dh
    @p = @dh.p.to_i
    @g = @dh.g.to_i
    send_kex_dh_gex_group transport
    @k_s = transport.server_host_key_algorithm.server_public_host_key
    @f   = @public_key
    message = receive_kex_dh_gex_init transport.receive
    @e   = message[:'e']
    @shared_secret = OpenSSL::BN.new(@dh.compute_key(OpenSSL::BN.new(@e)), 2).to_i
    send_kex_dh_gex_reply transport
  when Mode::CLIENT
    @min = 1024
    @n   = 2048
    @max = 8192
    send_kex_dh_gex_request transport
    message = receive_kex_dh_gex_group transport.receive
    @p   = message[:'p']
    @g   = message[:'g']
    initialize_dh [@p, @g]
    @e   = @public_key
    send_kex_dh_gex_init transport
    message = receive_kex_dh_gex_reply transport.receive
    @k_s = message[:'server public host key and certificates (K_S)']
    @f   = message[:'f']
    @shared_secret = OpenSSL::BN.new(@dh.compute_key(OpenSSL::BN.new(@f)), 2).to_i
  end
end