2 # Unix SMB/CIFS implementation.
3 # Copyright (C) Catalyst.Net Ltd 2023
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <https://www.gnu.org/licenses/>.
22 sys
.path
.insert(0, "bin/python")
23 os
.environ
["PYTHONUNBUFFERED"] = "1"
25 from samba
.dcerpc
import gkdi
, misc
26 from samba
.ndr
import ndr_pack
, ndr_unpack
30 def utf16_encoded_len(s
: str) -> int:
31 """Return the number of bytes required to encode a string as null‐terminated
34 raise ValueError("string contains an embedded null")
36 return len(s
.encode("utf-16-le")) + 2
39 class KeyEnvelopeTests(samba
.tests
.TestCase
):
41 b
"\x01\x00\x00\x00KDSK\x02\x00\x00\x00j\x01\x00\x00\x01\x00\x00\x00"
42 b
"\x0e\x00\x00\x001\"\x92\x9d'\xaf;\xb7\x10V\xae\xb1\x8e\xec\xa7\x1a"
43 b
"\x00\x00\x00\x00\x18\x00\x00\x00\x18\x00\x00\x00e\x00x\x00a\x00m\x00"
44 b
"p\x00l\x00e\x00.\x00c\x00o\x00m\x00\x00\x00e\x00x\x00a\x00m\x00p\x00l\x00"
45 b
"e\x00.\x00c\x00o\x00m\x00\x00\x00"
48 root_key_id
= misc
.GUID("9d922231-af27-b73b-1056-aeb18eeca71a")
50 domain_name
= "example.com"
51 forest_name
= "example.com"
53 def test_unpack(self
):
54 """Unpack a GKDI Key Envelope blob and check its fields."""
56 envelope
= ndr_unpack(gkdi
.KeyEnvelope
, self
.key_envelope_blob
)
58 self
.assertEqual(1, envelope
.version
)
59 self
.assertEqual(int.from_bytes(b
"KDSK", byteorder
="little"), envelope
.magic
)
60 self
.assertEqual(gkdi
.ENVELOPE_FLAG_KEY_MAY_ENCRYPT_NEW_DATA
, envelope
.flags
)
62 self
.assertEqual(362, envelope
.l0_index
)
63 self
.assertEqual(1, envelope
.l1_index
)
64 self
.assertEqual(14, envelope
.l2_index
)
66 self
.assertEqual(self
.root_key_id
, envelope
.root_key_id
)
68 self
.assertEqual(0, envelope
.additional_info_len
)
69 self
.assertFalse(envelope
.additional_info
)
71 self
.assertEqual(self
.domain_name
, envelope
.domain_name
)
72 self
.assertEqual(utf16_encoded_len(self
.domain_name
), envelope
.domain_name_len
)
73 self
.assertEqual(self
.forest_name
, envelope
.forest_name
)
74 self
.assertEqual(utf16_encoded_len(self
.forest_name
), envelope
.forest_name_len
)
77 """Create a GKDI Key Envelope object and test that it packs to the
80 envelope
= gkdi
.KeyEnvelope()
83 envelope
.flags
= gkdi
.ENVELOPE_FLAG_KEY_MAY_ENCRYPT_NEW_DATA
85 envelope
.l0_index
= 362
87 envelope
.l2_index
= 14
89 envelope
.root_key_id
= self
.root_key_id
91 envelope
.additional_info
= []
92 envelope
.additional_info_len
= 0
94 envelope
.domain_name
= self
.domain_name
95 envelope
.forest_name
= self
.forest_name
97 self
.assertEqual(self
.key_envelope_blob
, ndr_pack(envelope
))
100 class GroupKeyEnvelopeTests(samba
.tests
.TestCase
):
101 group_key_envelope_blob
= (
102 b
"\x01\x00\x00\x00KDSK\x00\x00\x00\x00j\x01\x00\x00\x01\x00\x00\x00"
103 b
"\x0e\x00\x00\x00\x8c\xc4\x8c\xdevp\x94\x97\x05m\x897{Z\x80R&\x00\x00\x00"
104 b
"\x1e\x00\x00\x00\x06\x00\x00\x00\x0c\x02\x00\x00\x00\x02\x00\x00"
105 b
"\x00\x08\x00\x00@\x00\x00\x00@\x00\x00\x00\x18\x00\x00\x00\x18\x00\x00\x00"
106 b
"S\x00P\x008\x000\x000\x00_\x001\x000\x008\x00_\x00C\x00T\x00R\x00_\x00"
107 b
"H\x00M\x00A\x00C\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x0e\x00"
108 b
"\x00\x00\x00\x00\x00\x00S\x00H\x00A\x005\x001\x002\x00\x00\x00D\x00H\x00"
109 b
"\x00\x00\x0c\x02\x00\x00DHPM\x00\x01\x00\x00\x87\xa8\xe6\x1d\xb4\xb6"
110 b
"f<\xff\xbb\xd1\x9ce\x19Y\x99\x8c\xee\xf6\x08f\r\xd0\xf2],\xee\xd4C^"
111 b
";\x00\xe0\r\xf8\xf1\xd6\x19W\xd4\xfa\xf7\xdfEa\xb2\xaa0\x16\xc3\xd9\x114\t"
112 b
"o\xaa;\xf4)m\x83\x0e\x9a| \x9e\x0cd\x97Qz\xbdZ\x8a\x9d0k\xcfg\xed\x91\xf9"
113 b
'\xe6r[GX\xc0"\xe0\xb1\xefBu\xbf{l[\xfc\x11\xd4_\x90\x88\xb9A\xf5N\xb1\xe5'
114 b
"\x9b\xb8\xbc9\xa0\xbf\x120\x7f\\O\xdbp\xc5\x81\xb2?v\xb6:\xca\xe1\xca\xa6"
115 b
"\xb7\x90-RRg5H\x8a\x0e\xf1<m\x9aQ\xbf\xa4\xab:\xd84w\x96RM\x8e\xf6\xa1"
116 b
"g\xb5\xa4\x18%\xd9g\xe1D\xe5\x14\x05d%\x1c\xca\xcb\x83\xe6\xb4"
117 b
"\x86\xf6\xb3\xca?yqP`&\xc0\xb8W\xf6\x89\x96(V\xde\xd4\x01\n\xbd\x0b"
118 b
"\xe6!\xc3\xa3\x96\nT\xe7\x10\xc3u\xf2cu\xd7\x01A\x03\xa4\xb5C0\xc1\x98"
119 b
"\xaf\x12a\x16\xd2'n\x11q_i8w\xfa\xd7\xef\t\xca\xdb\tJ\xe9\x1e\x1a"
120 b
"\x15\x97?\xb3,\x9bs\x13M\x0b.wPf`\xed\xbdHL\xa7\xb1\x8f!\xef T\x07\xf4"
121 b
"y:\x1a\x0b\xa1%\x10\xdb\xc1Pw\xbeF?\xffO\xedJ\xac\x0b\xb5U\xbe:l\x1b\x0ck"
122 b
"G\xb1\xbc7s\xbf~\x8cob\x90\x12(\xf8\xc2\x8c\xbb\x18\xa5Z\xe3\x13A\x00"
123 b
"\ne\x01\x96\xf91\xc7zW\xf2\xdd\xf4c\xe5\xe9\xec\x14Kw}\xe6*\xaa\xb8"
124 b
"\xa8b\x8a\xc3v\xd2\x82\xd6\xed8d\xe6y\x82B\x8e\xbc\x83\x1d\x144\x8fo/"
125 b
"\x91\x93\xb5\x04Z\xf2vqd\xe1\xdf\xc9g\xc1\xfb?.U\xa4\xbd\x1b\xff\xe8;"
126 b
"\x9c\x80\xd0R\xb9\x85\xd1\x82\xea\n\xdb*;s\x13\xd3\xfe\x14\xc8HK\x1e\x05%"
127 b
"\x88\xb9\xb7\xd2\xbb\xd2\xdf\x01a\x99\xec\xd0n\x15W\xcd\t\x15\xb35;\xbbd\xe0"
128 b
"\xec7\x7f\xd0(7\r\xf9+R\xc7\x89\x14(\xcd\xc6~\xb6\x18KR=\x1d\xb2F\xc3/c"
129 b
"\x07\x84\x90\xf0\x0e\xf8\xd6G\xd1H\xd4yTQ^#'\xcf\xef\x98\xc5\x82fKL\x0fl\xc4"
130 b
"\x16Ye\x00x\x00a\x00m\x00p\x00l\x00e\x00.\x00c\x00o\x00m\x00\x00\x00e\x00"
131 b
"x\x00a\x00m\x00p\x00l\x00e\x00.\x00c\x00o\x00m\x00\x00\x00D\x12\x1e\r[y"
132 b
'\xf4\x91\x92\xf4\xb8\xff\xc7;\x03@|Xs\xda\x051\xf9"A\xd6\xc1\x1c\xceA'
133 b
"\xa5\x05\x11\x84\x8f\xe3q\x81\xda\t\xcb\"\x8e\xbd\xa9p'\x0fM\xd6"
134 b
"\xe8\xa1E\x00\x8b\xc1\x8bw\x91\xac{\x1d\x8d\xba\x03P\x13-\xa5\xf2\xfc\x94<'"
135 b
"\xf3\xf6\x08\x17\xe3\xb4c\xd4\xc6\x08\xec\r\x03\x0e\xcd\xfdD\xe2\xbf\x90"
136 b
"\xeai\xb6\xb1x\xa9s\x88w\xeci\xf9\xb5\xc1\xc43\x1a4^\x0f\xfd\xa0He"
137 b
"(\x93\x95\x10\xc0\x85\xcb\x041D"
140 root_key_id
= misc
.GUID("de8cc48c-7076-9794-056d-89377b5a8052")
142 kdf_algorithm
= "SP800_108_CTR_HMAC"
145 b
"\x00\x00\x00\x00\x01\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00S\x00H\x00"
146 b
"A\x005\x001\x002\x00\x00\x00"
149 secret_agreement_algorithm
= "DH"
151 secret_agreement_parameters
= (
152 b
"\x0c\x02\x00\x00DHPM\x00\x01\x00\x00\x87\xa8\xe6\x1d\xb4\xb6f<"
153 b
"\xff\xbb\xd1\x9ce\x19Y\x99\x8c\xee\xf6\x08f\r\xd0\xf2],\xee\xd4C^;\x00"
154 b
"\xe0\r\xf8\xf1\xd6\x19W\xd4\xfa\xf7\xdfEa\xb2\xaa0\x16\xc3\xd9\x114\to\xaa"
155 b
";\xf4)m\x83\x0e\x9a| \x9e\x0cd\x97Qz\xbdZ\x8a\x9d0k\xcfg\xed\x91\xf9\xe6r"
156 b
'[GX\xc0"\xe0\xb1\xefBu\xbf{l[\xfc\x11\xd4_\x90\x88\xb9A\xf5N\xb1\xe5\x9b\xb8'
157 b
"\xbc9\xa0\xbf\x120\x7f\\O\xdbp\xc5\x81\xb2?v\xb6:\xca\xe1\xca\xa6\xb7\x90"
158 b
"-RRg5H\x8a\x0e\xf1<m\x9aQ\xbf\xa4\xab:\xd84w\x96RM\x8e\xf6\xa1g\xb5"
159 b
"\xa4\x18%\xd9g\xe1D\xe5\x14\x05d%\x1c\xca\xcb\x83\xe6\xb4\x86\xf6\xb3\xca?y"
160 b
"qP`&\xc0\xb8W\xf6\x89\x96(V\xde\xd4\x01\n\xbd\x0b\xe6!\xc3\xa3\x96\n"
161 b
"T\xe7\x10\xc3u\xf2cu\xd7\x01A\x03\xa4\xb5C0\xc1\x98\xaf\x12a\x16\xd2'n\x11q_"
162 b
"i8w\xfa\xd7\xef\t\xca\xdb\tJ\xe9\x1e\x1a\x15\x97?\xb3,\x9bs\x13M\x0b.wPf"
163 b
"`\xed\xbdHL\xa7\xb1\x8f!\xef T\x07\xf4y:\x1a\x0b\xa1%\x10\xdb\xc1Pw\xbeF?"
164 b
"\xffO\xedJ\xac\x0b\xb5U\xbe:l\x1b\x0ckG\xb1\xbc7s\xbf~\x8cob\x90\x12(\xf8"
165 b
"\xc2\x8c\xbb\x18\xa5Z\xe3\x13A\x00\ne\x01\x96\xf91\xc7zW\xf2\xdd\xf4c\xe5"
166 b
"\xe9\xec\x14Kw}\xe6*\xaa\xb8\xa8b\x8a\xc3v\xd2\x82\xd6\xed8d\xe6y\x82"
167 b
"B\x8e\xbc\x83\x1d\x144\x8fo/\x91\x93\xb5\x04Z\xf2vqd\xe1\xdf\xc9g\xc1\xfb?.U"
168 b
"\xa4\xbd\x1b\xff\xe8;\x9c\x80\xd0R\xb9\x85\xd1\x82\xea\n\xdb*;s"
169 b
"\x13\xd3\xfe\x14\xc8HK\x1e\x05%\x88\xb9\xb7\xd2\xbb\xd2\xdf\x01a\x99"
170 b
"\xec\xd0n\x15W\xcd\t\x15\xb35;\xbbd\xe0\xec7\x7f\xd0(7\r\xf9+R\xc7\x89\x14("
171 b
"\xcd\xc6~\xb6\x18KR=\x1d\xb2F\xc3/c\x07\x84\x90\xf0\x0e\xf8\xd6G\xd1H\xd4yTQ"
172 b
"^#'\xcf\xef\x98\xc5\x82fKL\x0fl\xc4\x16Y"
175 domain_name
= "example.com"
176 forest_name
= "example.com"
179 b
'D\x12\x1e\r[y\xf4\x91\x92\xf4\xb8\xff\xc7;\x03@|Xs\xda\x051\xf9"'
180 b
'A\xd6\xc1\x1c\xceA\xa5\x05\x11\x84\x8f\xe3q\x81\xda\t\xcb"\x8e\xbd'
181 b
"\xa9p'\x0fM\xd6\xe8\xa1E\x00\x8b\xc1\x8bw\x91\xac{\x1d\x8d\xba"
185 b
"\x03P\x13-\xa5\xf2\xfc\x94<'\xf3\xf6\x08\x17\xe3\xb4c\xd4\xc6\x08"
186 b
"\xec\r\x03\x0e\xcd\xfdD\xe2\xbf\x90\xeai\xb6\xb1x\xa9s\x88w\xeci\xf9\xb5\xc1"
187 b
"\xc43\x1a4^\x0f\xfd\xa0He(\x93\x95\x10\xc0\x85\xcb\x041D"
190 def test_unpack(self
):
191 """Unpack a GKDI Group Key Envelope blob and check its fields."""
193 envelope
= ndr_unpack(gkdi
.GroupKeyEnvelope
, self
.group_key_envelope_blob
)
195 self
.assertEqual(1, envelope
.version
)
196 self
.assertEqual(int.from_bytes(b
"KDSK", byteorder
="little"), envelope
.magic
)
197 self
.assertEqual(0, envelope
.flags
)
199 self
.assertEqual(362, envelope
.l0_index
)
200 self
.assertEqual(1, envelope
.l1_index
)
201 self
.assertEqual(14, envelope
.l2_index
)
203 self
.assertEqual(self
.root_key_id
, envelope
.root_key_id
)
205 self
.assertEqual(512, envelope
.private_key_len
)
206 self
.assertEqual(2048, envelope
.public_key_len
)
208 self
.assertEqual(self
.kdf_algorithm
, envelope
.kdf_algorithm
)
210 utf16_encoded_len(self
.kdf_algorithm
), envelope
.kdf_algorithm_len
212 self
.assertEqual(len(self
.kdf_parameters
), envelope
.kdf_parameters_len
)
213 self
.assertEqual(list(self
.kdf_parameters
), envelope
.kdf_parameters
)
216 utf16_encoded_len(self
.secret_agreement_algorithm
),
217 envelope
.secret_agreement_algorithm_len
,
220 self
.secret_agreement_algorithm
, envelope
.secret_agreement_algorithm
223 len(self
.secret_agreement_parameters
),
224 envelope
.secret_agreement_parameters_len
,
227 list(self
.secret_agreement_parameters
), envelope
.secret_agreement_parameters
230 self
.assertEqual(self
.domain_name
, envelope
.domain_name
)
231 self
.assertEqual(utf16_encoded_len(self
.domain_name
), envelope
.domain_name_len
)
232 self
.assertEqual(self
.forest_name
, envelope
.forest_name
)
233 self
.assertEqual(utf16_encoded_len(self
.forest_name
), envelope
.forest_name_len
)
235 self
.assertEqual(len(self
.l1_key
), envelope
.l1_key_len
)
236 self
.assertEqual(list(self
.l1_key
), envelope
.l1_key
)
237 self
.assertEqual(len(self
.l2_key
), envelope
.l2_key_len
)
238 self
.assertEqual(list(self
.l2_key
), envelope
.l2_key
)
241 """Create a GKDI Group Key Envelope object and test that it packs to the
244 envelope
= gkdi
.GroupKeyEnvelope()
249 envelope
.l0_index
= 362
250 envelope
.l1_index
= 1
251 envelope
.l2_index
= 14
253 envelope
.root_key_id
= self
.root_key_id
255 envelope
.private_key_len
= 512
256 envelope
.public_key_len
= 2048
258 envelope
.kdf_algorithm
= self
.kdf_algorithm
260 envelope
.kdf_parameters
= list(self
.kdf_parameters
)
261 envelope
.kdf_parameters_len
= len(self
.kdf_parameters
)
263 envelope
.secret_agreement_algorithm
= self
.secret_agreement_algorithm
265 envelope
.secret_agreement_parameters
= list(self
.secret_agreement_parameters
)
266 envelope
.secret_agreement_parameters_len
= len(self
.secret_agreement_parameters
)
268 envelope
.domain_name
= self
.domain_name
269 envelope
.forest_name
= self
.forest_name
271 envelope
.l1_key
= list(self
.l1_key
)
272 envelope
.l1_key_len
= len(self
.l1_key
)
274 envelope
.l2_key
= list(self
.l2_key
)
275 envelope
.l2_key_len
= len(self
.l2_key
)
277 self
.assertEqual(self
.group_key_envelope_blob
, ndr_pack(envelope
))
280 class KdfParametersTests(samba
.tests
.TestCase
):
281 kdf_parameters_blob
= (
282 b
"\x00\x00\x00\x00\x01\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00S\x00H\x00"
283 b
"A\x005\x001\x002\x00\x00\x00"
286 hash_algorithm
= "SHA512"
288 def test_unpack(self
):
289 """Unpack a GKDI KDF Parameters blob and check its fields."""
291 kdf_parameters
= ndr_unpack(gkdi
.KdfParameters
, self
.kdf_parameters_blob
)
293 self
.assertEqual(0, kdf_parameters
.padding_0
)
294 self
.assertEqual(1, kdf_parameters
.padding_1
)
295 self
.assertEqual(0, kdf_parameters
.padding_2
)
297 self
.assertEqual(self
.hash_algorithm
, kdf_parameters
.hash_algorithm
)
299 utf16_encoded_len(self
.hash_algorithm
), kdf_parameters
.hash_algorithm_len
303 """Create a GKDI KDF Parameters object and test that it packs to the
306 kdf_parameters
= gkdi
.KdfParameters()
307 kdf_parameters
.hash_algorithm
= self
.hash_algorithm
309 self
.assertEqual(self
.kdf_parameters_blob
, ndr_pack(kdf_parameters
))
312 class FfcDhParametersTests(samba
.tests
.TestCase
):
313 ffc_dh_parameters_blob
= (
314 b
"\x0c\x02\x00\x00DHPM\x00\x01\x00\x00\x87\xa8\xe6\x1d\xb4\xb6f<"
315 b
"\xff\xbb\xd1\x9ce\x19Y\x99\x8c\xee\xf6\x08f\r\xd0\xf2],\xee\xd4C^;\x00"
316 b
"\xe0\r\xf8\xf1\xd6\x19W\xd4\xfa\xf7\xdfEa\xb2\xaa0\x16\xc3\xd9\x114\to\xaa"
317 b
";\xf4)m\x83\x0e\x9a| \x9e\x0cd\x97Qz\xbdZ\x8a\x9d0k\xcfg\xed\x91\xf9\xe6r"
318 b
'[GX\xc0"\xe0\xb1\xefBu\xbf{l[\xfc\x11\xd4_\x90\x88\xb9A\xf5N\xb1\xe5\x9b\xb8'
319 b
"\xbc9\xa0\xbf\x120\x7f\\O\xdbp\xc5\x81\xb2?v\xb6:\xca\xe1\xca\xa6\xb7\x90"
320 b
"-RRg5H\x8a\x0e\xf1<m\x9aQ\xbf\xa4\xab:\xd84w\x96RM\x8e\xf6\xa1g\xb5"
321 b
"\xa4\x18%\xd9g\xe1D\xe5\x14\x05d%\x1c\xca\xcb\x83\xe6\xb4\x86\xf6\xb3\xca?y"
322 b
"qP`&\xc0\xb8W\xf6\x89\x96(V\xde\xd4\x01\n\xbd\x0b\xe6!\xc3\xa3\x96\n"
323 b
"T\xe7\x10\xc3u\xf2cu\xd7\x01A\x03\xa4\xb5C0\xc1\x98\xaf\x12a\x16\xd2'n\x11q_"
324 b
"i8w\xfa\xd7\xef\t\xca\xdb\tJ\xe9\x1e\x1a\x15\x97?\xb3,\x9bs\x13M\x0b.wPf"
325 b
"`\xed\xbdHL\xa7\xb1\x8f!\xef T\x07\xf4y:\x1a\x0b\xa1%\x10\xdb\xc1Pw\xbeF?"
326 b
"\xffO\xedJ\xac\x0b\xb5U\xbe:l\x1b\x0ckG\xb1\xbc7s\xbf~\x8cob\x90\x12(\xf8"
327 b
"\xc2\x8c\xbb\x18\xa5Z\xe3\x13A\x00\ne\x01\x96\xf91\xc7zW\xf2\xdd\xf4c\xe5"
328 b
"\xe9\xec\x14Kw}\xe6*\xaa\xb8\xa8b\x8a\xc3v\xd2\x82\xd6\xed8d\xe6y\x82"
329 b
"B\x8e\xbc\x83\x1d\x144\x8fo/\x91\x93\xb5\x04Z\xf2vqd\xe1\xdf\xc9g\xc1\xfb?.U"
330 b
"\xa4\xbd\x1b\xff\xe8;\x9c\x80\xd0R\xb9\x85\xd1\x82\xea\n\xdb*;s"
331 b
"\x13\xd3\xfe\x14\xc8HK\x1e\x05%\x88\xb9\xb7\xd2\xbb\xd2\xdf\x01a\x99"
332 b
"\xec\xd0n\x15W\xcd\t\x15\xb35;\xbbd\xe0\xec7\x7f\xd0(7\r\xf9+R\xc7\x89\x14("
333 b
"\xcd\xc6~\xb6\x18KR=\x1d\xb2F\xc3/c\x07\x84\x90\xf0\x0e\xf8\xd6G\xd1H\xd4yTQ"
334 b
"^#'\xcf\xef\x98\xc5\x82fKL\x0fl\xc4\x16Y"
338 b
"\x87\xa8\xe6\x1d\xb4\xb6f<\xff\xbb\xd1\x9ce\x19Y\x99\x8c\xee\xf6\x08"
339 b
"f\r\xd0\xf2],\xee\xd4C^;\x00\xe0\r\xf8\xf1\xd6\x19W\xd4\xfa\xf7\xdfE"
340 b
"a\xb2\xaa0\x16\xc3\xd9\x114\to\xaa;\xf4)m\x83\x0e\x9a| \x9e\x0cd\x97Qz\xbd"
341 b
'Z\x8a\x9d0k\xcfg\xed\x91\xf9\xe6r[GX\xc0"\xe0\xb1\xefBu\xbf{l[\xfc\x11'
342 b
"\xd4_\x90\x88\xb9A\xf5N\xb1\xe5\x9b\xb8\xbc9\xa0\xbf\x120\x7f\\O\xdbp\xc5"
343 b
"\x81\xb2?v\xb6:\xca\xe1\xca\xa6\xb7\x90-RRg5H\x8a\x0e\xf1<m\x9aQ\xbf\xa4\xab"
344 b
":\xd84w\x96RM\x8e\xf6\xa1g\xb5\xa4\x18%\xd9g\xe1D\xe5\x14\x05d%"
345 b
"\x1c\xca\xcb\x83\xe6\xb4\x86\xf6\xb3\xca?yqP`&\xc0\xb8W\xf6\x89\x96(V"
346 b
"\xde\xd4\x01\n\xbd\x0b\xe6!\xc3\xa3\x96\nT\xe7\x10\xc3u\xf2cu\xd7\x01A\x03"
347 b
"\xa4\xb5C0\xc1\x98\xaf\x12a\x16\xd2'n\x11q_i8w\xfa\xd7\xef\t\xca\xdb\tJ\xe9"
352 b
"?\xb3,\x9bs\x13M\x0b.wPf`\xed\xbdHL\xa7\xb1\x8f!\xef T\x07\xf4y:"
353 b
"\x1a\x0b\xa1%\x10\xdb\xc1Pw\xbeF?\xffO\xedJ\xac\x0b\xb5U\xbe:l\x1b\x0ckG\xb1"
354 b
"\xbc7s\xbf~\x8cob\x90\x12(\xf8\xc2\x8c\xbb\x18\xa5Z\xe3\x13A\x00\ne"
355 b
"\x01\x96\xf91\xc7zW\xf2\xdd\xf4c\xe5\xe9\xec\x14Kw}\xe6*\xaa\xb8\xa8b"
356 b
"\x8a\xc3v\xd2\x82\xd6\xed8d\xe6y\x82B\x8e\xbc\x83\x1d\x144\x8fo/\x91\x93"
357 b
"\xb5\x04Z\xf2vqd\xe1\xdf\xc9g\xc1\xfb?.U\xa4\xbd\x1b\xff\xe8;\x9c\x80"
358 b
"\xd0R\xb9\x85\xd1\x82\xea\n\xdb*;s\x13\xd3\xfe\x14\xc8HK\x1e\x05%\x88\xb9"
359 b
"\xb7\xd2\xbb\xd2\xdf\x01a\x99\xec\xd0n\x15W\xcd\t\x15\xb35;\xbbd\xe0\xec7"
360 b
"\x7f\xd0(7\r\xf9+R\xc7\x89\x14(\xcd\xc6~\xb6\x18KR=\x1d\xb2F\xc3/c\x07\x84"
361 b
"\x90\xf0\x0e\xf8\xd6G\xd1H\xd4yTQ^#'\xcf\xef\x98\xc5\x82fKL\x0fl\xc4\x16Y"
364 def test_unpack(self
):
365 """Unpack a GKDI FFC DH Parameters blob and check its fields."""
367 ffc_dh_parameters
= ndr_unpack(
368 gkdi
.FfcDhParameters
, self
.ffc_dh_parameters_blob
371 self
.assertEqual(len(self
.ffc_dh_parameters_blob
), ffc_dh_parameters
.length
)
373 int.from_bytes(b
"DHPM", byteorder
="little"), ffc_dh_parameters
.magic
376 self
.assertEqual(len(self
.field_order
), ffc_dh_parameters
.key_length
)
377 self
.assertEqual(list(self
.field_order
), ffc_dh_parameters
.field_order
)
378 self
.assertEqual(list(self
.generator
), ffc_dh_parameters
.generator
)
381 """Create a GKDI FFC DH Parameters object and test that it packs to the
384 ffc_dh_parameters
= gkdi
.FfcDhParameters()
386 ffc_dh_parameters
.field_order
= list(self
.field_order
)
387 ffc_dh_parameters
.generator
= list(self
.generator
)
388 self
.assertEqual(len(self
.field_order
), len(self
.generator
))
389 ffc_dh_parameters
.key_length
= len(self
.field_order
)
391 self
.assertEqual(self
.ffc_dh_parameters_blob
, ndr_pack(ffc_dh_parameters
))
394 if __name__
== "__main__":