1 #include <winpr/print.h>
3 #include <rdpear-common/ndr.h>
4 #include <rdpear-common/rdpear_common.h>
7 #define MAX(a, b) ((a) > (b)) ? (a) : (b)
10 #define MIN(a, b) ((a) < (b)) ? (a) : (b)
13 static BYTE nextValue(BYTE old, INT32 offset,
char symbol,
char startSymbol)
15 const INT32 uold = 16 * old;
16 const INT32 diff = symbol - startSymbol;
17 const INT32 res = uold + diff + offset;
18 return (BYTE)MIN(MAX(0, res), UINT8_MAX);
21 static BYTE* parseHexBlock(
const char* str,
size_t* plen)
26 BYTE* ret = malloc(strlen(str) / 2);
28 const char* ptr = str;
42 WLog_ERR(
"",
"error parsing hex block, unpaired char");
57 tmp = nextValue(tmp, 0, *ptr,
'0');
75 tmp = nextValue(tmp, 10, *ptr,
'a');
93 tmp = nextValue(tmp, 10, *ptr,
'A');
105 WLog_ERR(
"",
"invalid char in hex block");
115 static int TestNdrEarWrite(
int argc,
char* argv[])
121 BYTE buffer[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
124 wStream* s = Stream_New(NULL, 100);
128 NdrContext* context = ndr_context_new(FALSE, 1);
132 if (!ndr_write_KERB_ASN1_DATA(context, s, NULL, &asn1))
134 if (!ndr_treat_deferred_write(context, s))
141 ndr_context_destroy(&context);
142 Stream_Free(s, TRUE);
146 static int TestNdrEarRead(
int argc,
char* argv[])
154 NdrContext* context = ndr_context_new(FALSE, 1);
163 0x00, 0x00, 0x00, 0x00,
164 0x02, 0x00, 0x00, 0x00,
165 0x28, 0x00, 0x02, 0x00,
168 0x02, 0x00, 0x00, 0x00,
172 s = Stream_StaticInit(&staticS, payload,
sizeof(payload));
175 if (!ndr_read_KERB_ASN1_DATA(context, s, NULL, &asn1) || !ndr_treat_deferred_read(context, s) ||
176 asn1.Asn1BufferHints.count != 2 || *asn1.Asn1Buffer != 0x30)
178 KERB_ASN1_DATA_destroy(context, &asn1);
179 ndr_context_reset(context);
186 0x1c, 0x00, 0x02, 0x00,
188 0x0f, 0x00, 0x00, 0x00,
189 0x00, 0x00, 0x00, 0x00,
190 0x0e, 0x00, 0x00, 0x00,
192 0x48, 0x00, 0x41, 0x00, 0x52, 0x00, 0x44, 0x00, 0x45, 0x00, 0x4e, 0x00, 0x49, 0x00, 0x4e,
193 0x00, 0x47, 0x00, 0x33, 0x00, 0x2e, 0x00, 0x43, 0x00, 0x4f, 0x00, 0x4d, 0x00, 0x00, 0x00,
199 s = Stream_StaticInit(&staticS, payload2,
sizeof(payload2));
201 if (!ndr_read_RPC_UNICODE_STRING(context, s, NULL, &unicode) || !ndr_treat_deferred_read(context, s))
203 RPC_UNICODE_STRING_destroy(context, &unicode);
204 ndr_context_reset(context);
211 0x10, 0x00, 0x02, 0x00,
213 0x01, 0x00, 0x00, 0x00,
218 0x14, 0x00, 0x02, 0x00,
220 0x0f, 0x00, 0x00, 0x00,
221 0x00, 0x00, 0x00, 0x00,
222 0x0e, 0x00, 0x00, 0x00,
223 0x41, 0x00, 0x64, 0x00, 0x6d, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74,
224 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x75, 0x00, 0x72, 0x00, 0x00, 0x00,
230 s = Stream_StaticInit(&staticS, payload3,
sizeof(payload3));
231 if (!ndr_read_KERB_RPC_INTERNAL_NAME(context, s, NULL, &intName) || !ndr_treat_deferred_read(context, s))
233 KERB_RPC_INTERNAL_NAME_destroy(context, &intName);
234 ndr_context_reset(context);
240 0x03, 0x01, 0x03, 0x01,
241 0x04, 0x00, 0x02, 0x00,
242 0xf8, 0xca, 0x95, 0x11,
243 0x0c, 0x00, 0x02, 0x00,
244 0x18, 0x00, 0x02, 0x00,
245 0x20, 0x00, 0x02, 0x00,
246 0x00, 0x00, 0x00, 0x00,
247 0x24, 0x00, 0x02, 0x00,
248 0x2c, 0x00, 0x02, 0x00,
249 0x07, 0x00, 0x00, 0x00,
252 0x40, 0xe9, 0x12, 0xdf,
253 0x12, 0x00, 0x00, 0x00,
255 0x4c, 0x00, 0x00, 0x00,
256 0x08, 0x00, 0x02, 0x00,
258 0x4c, 0x00, 0x00, 0x00,
259 0xc4, 0x41, 0xee, 0x34,
260 0x82, 0x2b, 0x29, 0x61, 0xe2, 0x96, 0xb5, 0x75, 0x61, 0x2d, 0xbf, 0x86, 0x01, 0x00, 0x00, 0x00,
261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x08, 0x60, 0x2e,
262 0x30, 0x3e, 0xfe, 0x56, 0x11, 0xf0, 0x31, 0xf2, 0xd6, 0x2e, 0x3d, 0x33, 0xfe, 0xce, 0x56, 0x12,
263 0xbf, 0xb2, 0xe5, 0x86, 0x29, 0x8d, 0x29, 0x74, 0x1f, 0x8a, 0xf9, 0xb9, 0x8c, 0xd4, 0x86, 0x3a,
264 0x21, 0x92, 0xb2, 0x07, 0x95, 0x4b, 0xea, 0xee,
269 0x10, 0x00, 0x02, 0x00,
271 0x01, 0x00, 0x00, 0x00,
276 0x14, 0x00, 0x02, 0x00,
278 0x0f, 0x00, 0x00, 0x00,
279 0x00, 0x00, 0x00, 0x00,
280 0x0e, 0x00, 0x00, 0x00,
281 0x41, 0x00, 0x64, 0x00, 0x6d, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00,
282 0x72, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x75, 0x00, 0x72, 0x00,
287 0x1c, 0x00, 0x02, 0x00,
289 0x0f, 0x00, 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x00,
291 0x0e, 0x00, 0x00, 0x00,
292 0x48, 0x00, 0x41, 0x00, 0x52, 0x00, 0x44, 0x00, 0x45, 0x00, 0x4e, 0x00, 0x49, 0x00, 0x4e, 0x00,
293 0x47, 0x00, 0x33, 0x00, 0x2e, 0x00, 0x43, 0x00, 0x4f, 0x00, 0x4d, 0x00,
295 0x00, 0x00, 0x00, 0x00,
298 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00,
302 0x00, 0x00, 0x00, 0x00,
303 0x02, 0x00, 0x00, 0x00,
304 0x28, 0x00, 0x02, 0x00,
306 0x02, 0x00, 0x00, 0x00,
311 0x08, 0x00, 0x00, 0x00,
312 0x1b, 0x00, 0x00, 0x00,
313 0x30, 0x00, 0x02, 0x00,
315 0x1b, 0x00, 0x00, 0x00,
320 0x04, 0x10, 0xb9, 0x4f, 0xcd, 0xae, 0xd9, 0xa8, 0xff, 0x49, 0x69, 0x5a, 0xd1,
321 0x1d, 0x38, 0x49, 0xb6, 0x92, 0x00
323 size_t sizeofPayload4 =
sizeof(payload4);
326 size_t sizeofPayload4 = 0;
327 BYTE* payload4 = parseHexBlock(
"03 01 03 01 \
328 04 00 02 00 38 9e ef 6b 0c 00 02 00 18 00 02 00 \
329 20 00 02 00 00 00 00 00 24 00 02 00 2c 00 02 00 \
330 07 00 00 00 13 8a a5 a8 12 00 00 00 20 00 00 00 \
331 08 00 02 00 20 00 00 00 c9 03 42 a8 17 8f d9 c4 \
332 9b d2 c4 6e 73 64 98 7b 90 f5 9a 28 77 8e ca de \
333 29 2e a3 8d 8a 56 36 d5 01 00 01 00 10 00 02 00 \
334 01 00 00 00 1c 00 1e 00 14 00 02 00 0f 00 00 00 \
335 00 00 00 00 0e 00 00 00 41 00 64 00 6d 00 69 00 \
336 6e 00 69 00 73 00 74 00 72 00 61 00 74 00 65 00 \
337 75 00 72 00 1c 00 1e 00 1c 00 02 00 0f 00 00 00 \
338 00 00 00 00 0e 00 00 00 48 00 41 00 52 00 44 00 \
339 45 00 4e 00 49 00 4e 00 47 00 33 00 2e 00 43 00 \
340 4f 00 4d 00 00 00 00 00 00 00 00 00 00 00 00 00 \
341 02 00 00 00 28 00 02 00 02 00 00 00 30 00 00 00 \
342 08 00 00 00 1b 00 00 00 30 00 02 00 1b 00 00 00 \
343 30 19 a0 03 02 01 07 a1 12 04 10 e4 aa ff 2b 93 \
344 97 4c f2 5c 0b 49 85 72 92 94 54 00",
352 s = Stream_StaticInit(&staticS, payload4, sizeofPayload4);
353 if (!ndr_skip_bytes(context, s, 4) ||
354 !ndr_read_CreateApReqAuthenticatorReq(context, s, NULL, &createApReqAuthenticatorReq) ||
355 !ndr_treat_deferred_read(context, s) || createApReqAuthenticatorReq.KeyUsage != 7 ||
356 !createApReqAuthenticatorReq.EncryptionKey || createApReqAuthenticatorReq.SubKey ||
357 !createApReqAuthenticatorReq.ClientName ||
358 createApReqAuthenticatorReq.ClientName->nameHints.count != 1 ||
359 !createApReqAuthenticatorReq.ClientRealm || !createApReqAuthenticatorReq.AuthData ||
360 createApReqAuthenticatorReq.AuthData->Asn1BufferHints.count != 2 ||
361 !createApReqAuthenticatorReq.SkewTime ||
362 createApReqAuthenticatorReq.SkewTime->QuadPart != 0)
364 ndr_destroy_CreateApReqAuthenticatorReq(context, NULL, &createApReqAuthenticatorReq);
365 ndr_context_reset(context);
371 ndr_context_destroy(&context);
375 int TestNdrEar(
int argc,
char* argv[])
377 const int rc = TestNdrEarWrite(argc, argv);
380 return TestNdrEarRead(argc, argv);
2.2.2.1.4 CreateApReqAuthenticator
2.2.1.2.3 KERB_RPC_INTERNAL_NAME
2.3.10 RPC_UNICODE_STRING (MS-DTYP)