mtproto 0.0.8 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/data/tl-schema.json +42686 -0
  3. data/ext/aes_ige/extconf.rb +3 -9
  4. data/ext/factorization/extconf.rb +2 -0
  5. data/lib/mtproto/auth_key_generator.rb +68 -105
  6. data/lib/mtproto/binary.rb +21 -0
  7. data/lib/mtproto/client/api/check_password.rb +41 -0
  8. data/lib/mtproto/client/api/export_login_token.rb +27 -0
  9. data/lib/mtproto/client/api/get_dialogs.rb +21 -0
  10. data/lib/mtproto/client/api/get_history.rb +20 -0
  11. data/lib/mtproto/client/api/get_updates_difference.rb +21 -0
  12. data/lib/mtproto/client/api/get_updates_state.rb +14 -0
  13. data/lib/mtproto/client/api/get_users.rb +14 -0
  14. data/lib/mtproto/client/api/import_login_token.rb +23 -0
  15. data/lib/mtproto/client/api/send_code.rb +21 -0
  16. data/lib/mtproto/client/api/sign_in.rb +27 -0
  17. data/lib/mtproto/client/api.rb +36 -0
  18. data/lib/mtproto/client/rpc/response.rb +63 -0
  19. data/lib/mtproto/client/rpc.rb +60 -127
  20. data/lib/mtproto/client.rb +143 -32
  21. data/lib/mtproto/crypto/dh_key_exchange.rb +1 -2
  22. data/lib/mtproto/crypto/dh_validator.rb +17 -19
  23. data/lib/mtproto/crypto/factorization.rb +1 -1
  24. data/lib/mtproto/crypto/rsa_key.rb +2 -2
  25. data/lib/mtproto/crypto/srp.rb +117 -0
  26. data/lib/mtproto/delegate_methods.rb +11 -0
  27. data/lib/mtproto/errors.rb +8 -0
  28. data/lib/mtproto/message/message.rb +85 -0
  29. data/lib/mtproto/session.rb +1 -1
  30. data/lib/mtproto/tl/constructor_names.rb +2271 -0
  31. data/lib/mtproto/tl/constructors.rb +99 -0
  32. data/lib/mtproto/tl/object.rb +25 -0
  33. data/lib/mtproto/tl/objects/account_password.rb +69 -0
  34. data/lib/mtproto/tl/objects/authorization.rb +70 -0
  35. data/lib/mtproto/tl/objects/check_password.rb +43 -0
  36. data/lib/mtproto/tl/objects/client_dh_inner_data.rb +45 -0
  37. data/lib/mtproto/tl/objects/dh_gen_response.rb +46 -0
  38. data/lib/mtproto/tl/objects/dialogs.rb +453 -0
  39. data/lib/mtproto/tl/objects/export_login_token.rb +48 -0
  40. data/lib/mtproto/tl/objects/get_config.rb +13 -0
  41. data/lib/mtproto/tl/objects/get_dialogs.rb +51 -0
  42. data/lib/mtproto/tl/objects/get_difference.rb +34 -0
  43. data/lib/mtproto/tl/objects/get_history.rb +49 -0
  44. data/lib/mtproto/tl/objects/get_password.rb +13 -0
  45. data/lib/mtproto/tl/objects/get_state.rb +13 -0
  46. data/lib/mtproto/tl/objects/get_users.rb +16 -0
  47. data/lib/mtproto/{type → tl/objects}/gzip_packed.rb +6 -6
  48. data/lib/mtproto/tl/objects/help_config.rb +76 -0
  49. data/lib/mtproto/tl/objects/import_login_token.rb +37 -0
  50. data/lib/mtproto/tl/objects/init_connection.rb +57 -0
  51. data/lib/mtproto/tl/objects/invoke_with_layer.rb +20 -0
  52. data/lib/mtproto/tl/objects/login_token.rb +78 -0
  53. data/lib/mtproto/{type → tl/objects}/message.rb +3 -3
  54. data/lib/mtproto/tl/objects/messages.rb +162 -0
  55. data/lib/mtproto/{type → tl/objects}/msg_container.rb +1 -3
  56. data/lib/mtproto/{type → tl/objects}/new_session_created.rb +1 -3
  57. data/lib/mtproto/tl/objects/pq_inner_data.rb +66 -0
  58. data/lib/mtproto/tl/objects/req_dh_params.rb +63 -0
  59. data/lib/mtproto/tl/objects/req_pq_multi.rb +21 -0
  60. data/lib/mtproto/tl/objects/res_pq.rb +73 -0
  61. data/lib/mtproto/{type → tl/objects}/rpc_error.rb +1 -4
  62. data/lib/mtproto/tl/objects/send_code.rb +47 -0
  63. data/lib/mtproto/tl/objects/sent_code.rb +79 -0
  64. data/lib/mtproto/tl/objects/server_dh_inner_data.rb +74 -0
  65. data/lib/mtproto/tl/objects/server_dh_params.rb +53 -0
  66. data/lib/mtproto/tl/objects/set_client_dh_params.rb +46 -0
  67. data/lib/mtproto/tl/objects/sign_in.rb +45 -0
  68. data/lib/mtproto/tl/objects/update.rb +77 -0
  69. data/lib/mtproto/tl/objects/update_short.rb +20 -0
  70. data/lib/mtproto/tl/objects/update_short_message.rb +65 -0
  71. data/lib/mtproto/tl/objects/updates_difference.rb +152 -0
  72. data/lib/mtproto/tl/objects/updates_state.rb +35 -0
  73. data/lib/mtproto/tl/objects/users.rb +83 -0
  74. data/lib/mtproto/tl/schema.rb +102 -0
  75. data/lib/mtproto/transport/abridged_packet_codec.rb +35 -12
  76. data/lib/mtproto/transport/connection.rb +23 -0
  77. data/lib/mtproto/transport/errors.rb +11 -0
  78. data/lib/mtproto/transport/packet.rb +19 -0
  79. data/lib/mtproto/transport/tcp_connection.rb +57 -46
  80. data/lib/mtproto/updates_poller.rb +37 -33
  81. data/lib/mtproto/version.rb +1 -1
  82. data/lib/mtproto.rb +17 -27
  83. data/scripts/generate_constructors.rb +65 -0
  84. metadata +76 -61
  85. data/lib/mtproto/async/middleware/base.rb +0 -17
  86. data/lib/mtproto/async/middleware/flood_wait.rb +0 -42
  87. data/lib/mtproto/async/request.rb +0 -18
  88. data/lib/mtproto/async/request_queue.rb +0 -63
  89. data/lib/mtproto/async_client.rb +0 -201
  90. data/lib/mtproto/rpc/get_config.rb +0 -34
  91. data/lib/mtproto/rpc/get_contacts.rb +0 -29
  92. data/lib/mtproto/rpc/get_updates_difference.rb +0 -51
  93. data/lib/mtproto/rpc/get_updates_state.rb +0 -29
  94. data/lib/mtproto/rpc/get_users.rb +0 -29
  95. data/lib/mtproto/rpc/ping.rb +0 -33
  96. data/lib/mtproto/rpc/send_code.rb +0 -41
  97. data/lib/mtproto/rpc/send_message.rb +0 -47
  98. data/lib/mtproto/rpc/sign_in.rb +0 -48
  99. data/lib/mtproto/type/auth_key/dh_gen_response.rb +0 -37
  100. data/lib/mtproto/type/auth_key/req_dh_params.rb +0 -31
  101. data/lib/mtproto/type/auth_key/req_pq_multi.rb +0 -18
  102. data/lib/mtproto/type/auth_key/res_pq.rb +0 -62
  103. data/lib/mtproto/type/auth_key/server_dh_params.rb +0 -43
  104. data/lib/mtproto/type/auth_key/set_client_dh_params.rb +0 -25
  105. data/lib/mtproto/type/bad_msg_notification.rb +0 -46
  106. data/lib/mtproto/type/client_dh_inner_data.rb +0 -29
  107. data/lib/mtproto/type/code_settings.rb +0 -25
  108. data/lib/mtproto/type/config.rb +0 -124
  109. data/lib/mtproto/type/pq_inner_data.rb +0 -41
  110. data/lib/mtproto/type/rpc/auth/authorization.rb +0 -107
  111. data/lib/mtproto/type/rpc/auth/send_code.rb +0 -28
  112. data/lib/mtproto/type/rpc/auth/sent_code.rb +0 -36
  113. data/lib/mtproto/type/rpc/auth/sign_in.rb +0 -32
  114. data/lib/mtproto/type/rpc/contacts/contacts.rb +0 -155
  115. data/lib/mtproto/type/rpc/contacts/get_contacts.rb +0 -18
  116. data/lib/mtproto/type/rpc/help/config.rb +0 -35
  117. data/lib/mtproto/type/rpc/help/get_config.rb +0 -17
  118. data/lib/mtproto/type/rpc/init_connection.rb +0 -28
  119. data/lib/mtproto/type/rpc/invoke_with_layer.rb +0 -19
  120. data/lib/mtproto/type/rpc/messages/send_message.rb +0 -43
  121. data/lib/mtproto/type/rpc/messages/updates.rb +0 -87
  122. data/lib/mtproto/type/rpc/ping.rb +0 -18
  123. data/lib/mtproto/type/rpc/pong.rb +0 -46
  124. data/lib/mtproto/type/rpc/updates/difference.rb +0 -332
  125. data/lib/mtproto/type/rpc/updates/get_difference.rb +0 -42
  126. data/lib/mtproto/type/rpc/updates/get_state.rb +0 -17
  127. data/lib/mtproto/type/rpc/updates/state.rb +0 -59
  128. data/lib/mtproto/type/rpc/users/get_users.rb +0 -25
  129. data/lib/mtproto/type/rpc/users/users.rb +0 -99
  130. data/lib/mtproto/type/sent_code.rb +0 -128
  131. data/lib/mtproto/type/serializer.rb +0 -55
  132. data/lib/mtproto/type/server_dh_inner_data.rb +0 -85
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MTProto
4
+ module TL
5
+ module Constructors
6
+ # Common
7
+ VECTOR = 0x1cb5c415
8
+ BOOL_TRUE = 0x997275b5
9
+ GZIP_PACKED = 0x3072cfa1
10
+ MSG_CONTAINER = 0x73f1f8dc
11
+ RPC_RESULT = 0xf35c6d01
12
+ RPC_ERROR = 0x2144ca19
13
+ BAD_SERVER_SALT = 0xedab447b
14
+ BAD_MSG_NOTIFICATION = 0xa7eff811
15
+ NEW_SESSION_CREATED = 0x9ec20908
16
+
17
+ # Peers
18
+ PEER_USER = 0x59511722
19
+ PEER_CHAT = 0x36c6019a
20
+ PEER_CHANNEL = 0xa2a5371e
21
+ INPUT_PEER_EMPTY = 0x7f3b18ea
22
+ INPUT_PEER_USER = 0xdde8a54c
23
+ INPUT_PEER_CHAT = 0x35a95cb9
24
+ INPUT_PEER_CHANNEL = 0x27bcbbfc
25
+ INPUT_USER_SELF = 0xf7c1b13f
26
+ INPUT_CHECK_PASSWORD_SRP = 0xd27ff082
27
+
28
+ # Auth key exchange
29
+ REQ_PQ_MULTI = 0xbe7e8ef1
30
+ RES_PQ = 0x05162463
31
+ PQ_INNER_DATA_DC = 0xa9f55f95
32
+ PQ_INNER_DATA_TEMP_DC = 0x56fddf88
33
+ REQ_DH_PARAMS = 0xd712e4be
34
+ SERVER_DH_PARAMS_OK = 0xd0e8075c
35
+ SERVER_DH_INNER_DATA = 0xb5890dba
36
+ CLIENT_DH_INNER_DATA = 0x6643b654
37
+ SET_CLIENT_DH_PARAMS = 0xf5045f1f
38
+ DH_GEN_OK = 0x3bcbf734
39
+ DH_GEN_RETRY = 0x46dc1fb9
40
+ DH_GEN_FAIL = 0xa69dae02
41
+
42
+ # Connection
43
+ INVOKE_WITH_LAYER = 0xda9b0d0d
44
+ INIT_CONNECTION = 0xc1cd5ea9
45
+ HELP_GET_CONFIG = 0xc4f9186b
46
+ CONFIG = 0xcc1a241e
47
+
48
+ # Auth
49
+ AUTH_SEND_CODE = 0xa677244f
50
+ AUTH_SENT_CODE = 0x5e002502
51
+ AUTH_SENT_CODE_TYPE_APP = 0x3dbb5986
52
+ AUTH_SENT_CODE_TYPE_SMS = 0xc000bba2
53
+ AUTH_SENT_CODE_TYPE_CALL = 0x5353e5a7
54
+ CODE_SETTINGS = 0xad253d78
55
+ AUTH_SIGN_IN = 0x8d52a951
56
+ AUTH_AUTHORIZATION = 0x2ea2c0d4
57
+ AUTH_AUTHORIZATION_SIGN_UP_REQUIRED = 0x44747e9a
58
+ AUTH_CHECK_PASSWORD = 0xd18b4d16
59
+ AUTH_EXPORT_LOGIN_TOKEN = 0xb7e085fe
60
+ AUTH_IMPORT_LOGIN_TOKEN = 0x95ac5ce4
61
+ AUTH_LOGIN_TOKEN = 0x629f1980
62
+ AUTH_LOGIN_TOKEN_MIGRATE_TO = 0x068e9916
63
+ AUTH_LOGIN_TOKEN_SUCCESS = 0x390d5c5e
64
+
65
+ # Account
66
+ ACCOUNT_GET_PASSWORD = 0x548a30f5
67
+ ACCOUNT_PASSWORD = 0x957b50fb
68
+ PASSWORD_KDF_ALGO_SHA256_MOD_POW = 0x3a912d4a
69
+
70
+ # Users
71
+ USERS_GET_USERS = 0x0d91a548
72
+ USER = 0x020b1422
73
+
74
+ # Messages
75
+ MESSAGES_GET_DIALOGS = 0xa0f4cb4f
76
+ MESSAGES_GET_HISTORY = 0x4423e6c5
77
+ MESSAGES_DIALOGS = 0x15ba6c40
78
+ MESSAGES_DIALOGS_SLICE = 0x71e094f3
79
+ MESSAGE = 0x9815cec8
80
+ DIALOG = 0xd58a08c6
81
+ CHAT = 0x41cbf256
82
+ CHAT_FORBIDDEN = 0x6592a1a7
83
+ CHANNEL = 0xfe685355
84
+ CHANNEL_FORBIDDEN = 0x17d493d5
85
+
86
+ # Updates
87
+ UPDATE_NEW_MESSAGE = 0x1f2b0afd
88
+ UPDATE_SHORT = 0x78d4dec1
89
+ UPDATE_SHORT_MESSAGE = 0x313bc7f8
90
+ UPDATES_GET_STATE = 0xedd4882a
91
+ UPDATES_STATE = 0xa56c2a3e
92
+ UPDATES_GET_DIFFERENCE = 0x19c2f763
93
+ UPDATES_DIFFERENCE_EMPTY = 0x5d75a138
94
+ UPDATES_DIFFERENCE = 0x00f49ca0
95
+ UPDATES_DIFFERENCE_SLICE = 0xa8fb1981
96
+ UPDATES_DIFFERENCE_TOO_LONG = 0x4afe8f6d
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MTProto
4
+ module TL
5
+ class Object
6
+ extend Binary
7
+
8
+ attr_reader :constructor, :payload
9
+
10
+ def initialize(constructor, payload)
11
+ @constructor = constructor
12
+ @payload = payload
13
+ end
14
+
15
+ def self.parse(message)
16
+ body = message.body
17
+ constructor_id = b_u32(body[0, 4])
18
+ constructor = ConstructorNames::NAMES.fetch(constructor_id)
19
+ payload = body[4..]
20
+
21
+ new(constructor, payload)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MTProto
4
+ module TL
5
+ class AccountPassword
6
+ attr_reader :has_password, :current_algo, :srp_b, :srp_id
7
+
8
+ def initialize(has_password:, current_algo: nil, srp_b: nil, srp_id: nil)
9
+ @has_password = has_password
10
+ @current_algo = current_algo
11
+ @srp_b = srp_b
12
+ @srp_id = srp_id
13
+ end
14
+
15
+ def self.parse(data)
16
+ constructor = data[0, 4].unpack1('L<')
17
+ raise UnexpectedConstructorError, constructor unless constructor == Constructors::ACCOUNT_PASSWORD
18
+
19
+ offset = 4
20
+ flags = data[offset, 4].unpack1('L<')
21
+ offset += 4
22
+
23
+ has_password = flags.anybits?(1 << 2)
24
+
25
+ return new(has_password: false) unless has_password
26
+
27
+ algo_constructor = data[offset, 4].unpack1('L<')
28
+ offset += 4
29
+
30
+ current_algo = nil
31
+ if algo_constructor == Constructors::PASSWORD_KDF_ALGO_SHA256_MOD_POW
32
+ salt1, offset = read_tl_bytes(data, offset)
33
+ salt2, offset = read_tl_bytes(data, offset)
34
+ g = data[offset, 4].unpack1('l<')
35
+ offset += 4
36
+ p, offset = read_tl_bytes(data, offset)
37
+
38
+ current_algo = { salt1: salt1, salt2: salt2, g: g, p: p }
39
+ end
40
+
41
+ srp_b, offset = read_tl_bytes(data, offset)
42
+ srp_id = data[offset, 8].unpack1('Q<')
43
+
44
+ new(has_password: true, current_algo: current_algo, srp_b: srp_b, srp_id: srp_id)
45
+ end
46
+
47
+ class << self
48
+ private
49
+
50
+ def read_tl_bytes(data, offset)
51
+ first_byte = data.getbyte(offset)
52
+ if first_byte < 254
53
+ len = first_byte
54
+ bytes = data[offset + 1, len]
55
+ total = 1 + len
56
+ else
57
+ len = data.getbyte(offset + 1) |
58
+ (data.getbyte(offset + 2) << 8) |
59
+ (data.getbyte(offset + 3) << 16)
60
+ bytes = data[offset + 4, len]
61
+ total = 4 + len
62
+ end
63
+ padding = (4 - (total % 4)) % 4
64
+ [bytes, offset + total + padding]
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MTProto
4
+ module TL
5
+ class Authorization
6
+ attr_reader :user_id, :access_hash, :flags, :sign_up_required
7
+
8
+ def initialize(user_id: nil, access_hash: nil, flags: 0, sign_up_required: false)
9
+ @user_id = user_id
10
+ @access_hash = access_hash
11
+ @flags = flags
12
+ @sign_up_required = sign_up_required
13
+ end
14
+
15
+ def authorization?
16
+ !@sign_up_required && @user_id
17
+ end
18
+
19
+ def self.parse(data)
20
+ constructor = data[0, 4].unpack1('L<')
21
+
22
+ return new(sign_up_required: true) if constructor == Constructors::AUTH_AUTHORIZATION_SIGN_UP_REQUIRED
23
+ raise UnexpectedConstructorError, constructor unless constructor == Constructors::AUTH_AUTHORIZATION
24
+
25
+ offset = 4
26
+
27
+ flags = data[offset, 4].unpack1('L<')
28
+ offset += 4
29
+
30
+ offset += 4 if flags.anybits?(1 << 0) # tmp_sessions
31
+ offset += 4 if flags.anybits?(1 << 1) # otherwise_relogin_days
32
+
33
+ offset = skip_tl_bytes(data, offset) if flags.anybits?(1 << 2) # future_auth_token
34
+
35
+ # user#20b1422 flags:# flags2:# id:long access_hash:flags.0?long ...
36
+ offset += 4 # user constructor
37
+
38
+ user_flags = data[offset, 4].unpack1('L<')
39
+ offset += 4
40
+
41
+ offset += 4 # flags2
42
+
43
+ user_id = data[offset, 8].unpack1('Q<')
44
+ offset += 8
45
+
46
+ access_hash = nil
47
+ access_hash = data[offset, 8].unpack1('Q<') if user_flags.anybits?(1 << 0)
48
+
49
+ new(user_id: user_id, access_hash: access_hash, flags: flags)
50
+ end
51
+
52
+ class << self
53
+ private
54
+
55
+ def skip_tl_bytes(data, offset)
56
+ first_byte = data.getbyte(offset)
57
+ if first_byte < 254
58
+ total = 1 + first_byte
59
+ else
60
+ len = data.getbyte(offset + 1) |
61
+ (data.getbyte(offset + 2) << 8) |
62
+ (data.getbyte(offset + 3) << 16)
63
+ total = 4 + len
64
+ end
65
+ offset + total + ((4 - (total % 4)) % 4)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MTProto
4
+ module TL
5
+ class CheckPassword
6
+ include Binary
7
+
8
+ attr_reader :srp_id, :a, :m1
9
+
10
+ def initialize(srp_id:, a:, m1:)
11
+ @srp_id = srp_id
12
+ @a = a
13
+ @m1 = m1
14
+ end
15
+
16
+ def body
17
+ u32_b(Constructors::AUTH_CHECK_PASSWORD) +
18
+ u32_b(Constructors::INPUT_CHECK_PASSWORD_SRP) +
19
+ u64_b(@srp_id) +
20
+ serialize_tl_bytes(@a) +
21
+ serialize_tl_bytes(@m1)
22
+ end
23
+
24
+ private
25
+
26
+ def serialize_tl_bytes(data)
27
+ bytes = data.bytes
28
+ length = bytes.length
29
+
30
+ if length <= 253
31
+ [length] + bytes + padding(length + 1)
32
+ else
33
+ [254] + u32_b(length)[0, 3] + bytes + padding(length + 4)
34
+ end
35
+ end
36
+
37
+ def padding(current_length)
38
+ pad_length = (4 - (current_length % 4)) % 4
39
+ [0] * pad_length
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MTProto
4
+ module TL
5
+ class ClientDHInnerData
6
+ include Binary
7
+
8
+ attr_reader :nonce, :server_nonce, :retry_id, :g_b
9
+
10
+ def initialize(nonce:, server_nonce:, retry_id:, g_b:)
11
+ @nonce = nonce
12
+ @server_nonce = server_nonce
13
+ @retry_id = retry_id
14
+ @g_b = g_b
15
+ end
16
+
17
+ def body
18
+ result = u32_b(Constructors::CLIENT_DH_INNER_DATA)
19
+ result += @nonce.bytes
20
+ result += @server_nonce.bytes
21
+ result += u64_b(@retry_id)
22
+ result += serialize_tl_bytes(@g_b.bytes)
23
+
24
+ result
25
+ end
26
+
27
+ private
28
+
29
+ def serialize_tl_bytes(bytes)
30
+ length = bytes.length
31
+
32
+ if length <= 253
33
+ [length] + bytes + padding(length + 1)
34
+ else
35
+ [254] + u32_b(length)[0, 3] + bytes + padding(length + 4)
36
+ end
37
+ end
38
+
39
+ def padding(current_length)
40
+ pad_length = (4 - (current_length % 4)) % 4
41
+ [0] * pad_length
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MTProto
4
+ module TL
5
+ class DHGenResponse
6
+ extend Binary
7
+
8
+ attr_reader :status, :nonce, :server_nonce, :new_nonce_hash
9
+
10
+ def self.parse(message)
11
+ data = message.body
12
+ constructor = b_u32(data[0, 4])
13
+
14
+ status = case constructor
15
+ when Constructors::DH_GEN_OK then :ok
16
+ when Constructors::DH_GEN_RETRY then :retry
17
+ when Constructors::DH_GEN_FAIL then :fail
18
+ else raise "Unexpected constructor: 0x#{constructor.to_s(16)}"
19
+ end
20
+
21
+ offset = 4
22
+ nonce = data[offset, 16].pack('C*')
23
+ offset += 16
24
+ server_nonce = data[offset, 16].pack('C*')
25
+ offset += 16
26
+ new_nonce_hash = data[offset, 16].pack('C*')
27
+
28
+ new(
29
+ status: status,
30
+ nonce: nonce,
31
+ server_nonce: server_nonce,
32
+ new_nonce_hash: new_nonce_hash
33
+ )
34
+ end
35
+
36
+ private
37
+
38
+ def initialize(status:, nonce:, server_nonce:, new_nonce_hash:)
39
+ @status = status
40
+ @nonce = nonce
41
+ @server_nonce = server_nonce
42
+ @new_nonce_hash = new_nonce_hash
43
+ end
44
+ end
45
+ end
46
+ end