Class: TTTLS13::Message::Extension::KeyShare

Inherits:
Object
  • Object
show all
Defined in:
lib/tttls1.3/message/extension/key_share.rb

Overview

rubocop: disable Metrics/ClassLength

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(msg_type:, key_share_entry: []) ⇒ KeyShare

rubocop: disable Metrics/CyclomaticComplexity rubocop: disable Metrics/PerceivedComplexity

Parameters:

Raises:



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/tttls1.3/message/extension/key_share.rb', line 20

def initialize(msg_type:, key_share_entry: [])
  @extension_type = ExtensionType::KEY_SHARE
  @msg_type = msg_type
  @key_share_entry = key_share_entry || []
  raise Error::ErrorAlerts, :internal_error \
    unless (@msg_type == HandshakeType::CLIENT_HELLO &&
            @key_share_entry.length >= 0 &&
            @key_share_entry.all?(&:valid_key_share_client_hello?)) ||
           (@msg_type == HandshakeType::SERVER_HELLO &&
            @key_share_entry.length == 1 &&
            @key_share_entry.first.valid_key_share_server_hello?) ||
           (@msg_type == HandshakeType::HELLO_RETRY_REQUEST &&
            @key_share_entry.length == 1 &&
            @key_share_entry.first.valid_key_share_hello_retry_request?)
end

Instance Attribute Details

#extension_typeObject (readonly)

Returns the value of attribute extension_type.



10
11
12
# File 'lib/tttls1.3/message/extension/key_share.rb', line 10

def extension_type
  @extension_type
end

#key_share_entryObject (readonly)

Returns the value of attribute key_share_entry.



12
13
14
# File 'lib/tttls1.3/message/extension/key_share.rb', line 12

def key_share_entry
  @key_share_entry
end

#msg_typeObject (readonly)

Returns the value of attribute msg_type.



11
12
13
# File 'lib/tttls1.3/message/extension/key_share.rb', line 11

def msg_type
  @msg_type
end

Class Method Details

.deserialize(binary, msg_type) ⇒ TTTLS13::Message::Extensions::KeyShare?

rubocop: disable Metrics/CyclomaticComplexity

Parameters:

Returns:

  • (TTTLS13::Message::Extensions::KeyShare, nil)

Raises:



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/tttls1.3/message/extension/key_share.rb', line 60

def self.deserialize(binary, msg_type)
  raise Error::ErrorAlerts, :internal_error if binary.nil?

  case msg_type
  when HandshakeType::CLIENT_HELLO
    key_share_entry = deserialize_keyshare_ch(binary)
    return nil \
      unless key_share_entry.all?(&:valid_key_share_client_hello?)
  when HandshakeType::SERVER_HELLO
    key_share_entry = deserialize_keyshare_sh(binary)
    return nil \
      unless key_share_entry.first.valid_key_share_server_hello?
  when HandshakeType::HELLO_RETRY_REQUEST
    key_share_entry = deserialize_keyshare_hrr(binary)
    return nil \
      unless key_share_entry.first.valid_key_share_hello_retry_request?
  else
    raise Error::ErrorAlerts, :internal_error
  end
  return nil if key_share_entry.nil?

  KeyShare.new(msg_type: msg_type,
               key_share_entry: key_share_entry)
end

.gen_ch_key_share(groups) ⇒ TTTLS13::Message::Extensions::KeyShare, Hash of NamedGroup => OpenSSL::PKey::EC.$Object

Parameters:

Returns:

  • (TTTLS13::Message::Extensions::KeyShare)
  • (Hash of NamedGroup => OpenSSL::PKey::EC.$Object)


90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/tttls1.3/message/extension/key_share.rb', line 90

def self.gen_ch_key_share(groups)
  priv_keys = {}
  kse = groups.map do |group|
    curve = NamedGroup.curve_name(group)
    ec = OpenSSL::PKey::EC.new(curve)
    ec.generate_key!
    # store private key to do the key-exchange
    priv_keys.store(group, ec)
    KeyShareEntry.new(
      group: group,
      key_exchange: ec.public_key.to_octet_string(:uncompressed)
    )
  end

  key_share = KeyShare.new(
    msg_type: HandshakeType::CLIENT_HELLO,
    key_share_entry: kse
  )

  [key_share, priv_keys]
end

.gen_hrr_key_share(group) ⇒ TTTLS13::Message::Extensions::KeyShare

Parameters:

Returns:

  • (TTTLS13::Message::Extensions::KeyShare)


137
138
139
140
141
142
143
# File 'lib/tttls1.3/message/extension/key_share.rb', line 137

def self.gen_hrr_key_share(group)
  kse = KeyShareEntry.new(group: group)
  KeyShare.new(
    msg_type: HandshakeType::HELLO_RETRY_REQUEST,
    key_share_entry: [kse]
  )
end

.gen_sh_key_share(group) ⇒ TTTLS13::Message::Extensions::KeyShare, OpenSSL::PKey::EC.$Object

Parameters:

Returns:

  • (TTTLS13::Message::Extensions::KeyShare)
  • (OpenSSL::PKey::EC.$Object)


116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/tttls1.3/message/extension/key_share.rb', line 116

def self.gen_sh_key_share(group)
  curve = NamedGroup.curve_name(group)
  ec = OpenSSL::PKey::EC.new(curve)
  ec.generate_key!

  key_share = KeyShare.new(
    msg_type: HandshakeType::SERVER_HELLO,
    key_share_entry: [
      KeyShareEntry.new(
        group: group,
        key_exchange: ec.public_key.to_octet_string(:uncompressed)
      )
    ]
  )

  [key_share, ec]
end

Instance Method Details

#serializeString

Returns:

  • (String)

Raises:



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/tttls1.3/message/extension/key_share.rb', line 41

def serialize
  case @msg_type
  when HandshakeType::CLIENT_HELLO
    binary = @key_share_entry.map(&:serialize).join.prefix_uint16_length
  when HandshakeType::SERVER_HELLO, HandshakeType::HELLO_RETRY_REQUEST
    binary = @key_share_entry.first.serialize
  else
    raise Error::ErrorAlerts, :internal_error
  end
  @extension_type + binary.prefix_uint16_length
end