Module: HrrRbSsh::Transport::KexAlgorithm::DiffieHellmanGroupExchange

Includes:
IvComputable
Included in:
DiffieHellmanGroupExchangeSha1, DiffieHellmanGroupExchangeSha256
Defined in:
lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb,
lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange/h0.rb

Defined Under Namespace

Modules: H0

Instance Method Summary collapse

Methods included from IvComputable

#build_key, #iv_c_to_s, #iv_s_to_c, #key_c_to_s, #key_s_to_c, #mac_c_to_s, #mac_s_to_c

Instance Method Details

#hash(transport) ⇒ Object



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
# File 'lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb', line 60

def hash transport
  e = @e
  k = shared_secret
  f = pub_key

  h0_payload = {
    :'V_C' => transport.v_c,
    :'V_S' => transport.v_s,
    :'I_C' => transport.i_c,
    :'I_S' => transport.i_s,
    :'K_S' => transport.server_host_key_algorithm.server_public_host_key,
    :'min' => @min,
    :'n'   => @n,
    :'max' => @max,
    :'p'   => @dh.p.to_i,
    :'g'   => @dh.g.to_i,
    :'e'   => e,
    :'f'   => f,
    :'k'   => k,
  }
  h0 = H0.encode h0_payload

  h = OpenSSL::Digest.digest self.class::DIGEST, h0

  h
end

#initializeObject



15
16
17
# File 'lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb', line 15

def initialize
  @logger = Logger.new(self.class.name)
end

#pub_keyObject



56
57
58
# File 'lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb', line 56

def pub_key
  f = @dh.pub_key.to_i
end

#receive_kex_dh_gex_init(payload) ⇒ Object



110
111
112
113
# File 'lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb', line 110

def receive_kex_dh_gex_init payload
  message = Message::SSH_MSG_KEX_DH_GEX_INIT.decode payload
  set_e message[:'e']
end

#receive_kex_dh_gex_request(payload) ⇒ Object



93
94
95
96
97
98
# File 'lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb', line 93

def receive_kex_dh_gex_request payload
  message = Message::SSH_MSG_KEX_DH_GEX_REQUEST.decode payload
  @min = message[:'min']
  @n   = message[:'n']
  @max = message[:'max']
end

#send_kex_dh_gex_group(transport) ⇒ Object



100
101
102
103
104
105
106
107
108
# File 'lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb', line 100

def send_kex_dh_gex_group transport
  message = {
    :'message number' => Message::SSH_MSG_KEX_DH_GEX_GROUP::VALUE,
    :'p'              => @dh.p.to_i,
    :'g'              => @dh.g.to_i,
  }
  payload = Message::SSH_MSG_KEX_DH_GEX_GROUP.encode message
  transport.send payload
end

#send_kex_dh_gex_reply(transport) ⇒ Object



115
116
117
118
119
120
121
122
123
124
# File 'lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb', line 115

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)' => transport.server_host_key_algorithm.server_public_host_key,
    :'f'                                             => pub_key,
    :'signature of H'                                => sign(transport),
  }
  payload = Message::SSH_MSG_KEX_DH_GEX_REPLY.encode message
  transport.send payload
end

#set_dhObject



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb', line 32

def set_dh
  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 = candidate[1]
  g = 2
  @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!
end

#set_e(e) ⇒ Object



48
49
50
# File 'lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb', line 48

def set_e e
  @e = e
end

#shared_secretObject



52
53
54
# File 'lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb', line 52

def shared_secret
  k = OpenSSL::BN.new(@dh.compute_key(OpenSSL::BN.new(@e)), 2).to_i
end

#sign(transport) ⇒ Object



87
88
89
90
91
# File 'lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb', line 87

def sign transport
  h = hash transport
  s = transport.server_host_key_algorithm.sign h
  s
end

#start(transport, mode) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb', line 19

def start transport, mode
  case mode
  when Mode::SERVER
    receive_kex_dh_gex_request transport.receive
    set_dh
    send_kex_dh_gex_group transport
    receive_kex_dh_gex_init transport.receive
    send_kex_dh_gex_reply transport
  else
    raise "unsupported mode"
  end
end