FreeRDP
Loading...
Searching...
No Matches
TestSchannel.c
1
2#include <winpr/crt.h>
3#include <winpr/sspi.h>
4#include <winpr/file.h>
5#include <winpr/pipe.h>
6#include <winpr/path.h>
7#include <winpr/tchar.h>
8#include <winpr/print.h>
9#include <winpr/synch.h>
10#include <winpr/thread.h>
11#include <winpr/crypto.h>
12#include <winpr/wlog.h>
13#include <winpr/schannel.h>
14
15static BOOL g_ClientWait = FALSE;
16static BOOL g_ServerWait = FALSE;
17
18static HANDLE g_ClientReadPipe = NULL;
19static HANDLE g_ClientWritePipe = NULL;
20static HANDLE g_ServerReadPipe = NULL;
21static HANDLE g_ServerWritePipe = NULL;
22
23static const BYTE test_localhost_crt[1029] = {
24 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
25 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x43,
26 0x79, 0x6A, 0x43, 0x43, 0x41, 0x62, 0x4B, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x45,
27 0x63, 0x61, 0x64, 0x63, 0x72, 0x7A, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47,
28 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x41, 0x55, 0x4D, 0x52, 0x49, 0x77,
29 0x45, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x77, 0x6C, 0x73, 0x0A, 0x62, 0x32, 0x4E,
30 0x68, 0x62, 0x47, 0x68, 0x76, 0x63, 0x33, 0x51, 0x77, 0x48, 0x68, 0x63, 0x4E, 0x4D, 0x54, 0x4D,
31 0x78, 0x4D, 0x44, 0x45, 0x78, 0x4D, 0x44, 0x59, 0x78, 0x4E, 0x7A, 0x55, 0x31, 0x57, 0x68, 0x63,
32 0x4E, 0x4D, 0x54, 0x51, 0x78, 0x4D, 0x44, 0x45, 0x78, 0x4D, 0x44, 0x59, 0x78, 0x4E, 0x7A, 0x55,
33 0x31, 0x57, 0x6A, 0x41, 0x55, 0x4D, 0x52, 0x49, 0x77, 0x45, 0x41, 0x59, 0x44, 0x0A, 0x56, 0x51,
34 0x51, 0x44, 0x45, 0x77, 0x6C, 0x73, 0x62, 0x32, 0x4E, 0x68, 0x62, 0x47, 0x68, 0x76, 0x63, 0x33,
35 0x51, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4D, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49,
36 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77,
37 0x41, 0x77, 0x67, 0x67, 0x45, 0x4B, 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x43, 0x33, 0x0A, 0x65,
38 0x6E, 0x33, 0x68, 0x5A, 0x4F, 0x53, 0x33, 0x6B, 0x51, 0x2F, 0x55, 0x54, 0x30, 0x53, 0x45, 0x6C,
39 0x30, 0x48, 0x6E, 0x50, 0x79, 0x64, 0x48, 0x75, 0x35, 0x39, 0x61, 0x69, 0x71, 0x64, 0x73, 0x64,
40 0x53, 0x55, 0x74, 0x6E, 0x43, 0x41, 0x37, 0x46, 0x66, 0x74, 0x30, 0x4F, 0x36, 0x51, 0x79, 0x68,
41 0x49, 0x71, 0x58, 0x7A, 0x30, 0x47, 0x32, 0x53, 0x76, 0x77, 0x4C, 0x54, 0x62, 0x79, 0x68, 0x0A,
42 0x59, 0x54, 0x68, 0x31, 0x36, 0x78, 0x31, 0x72, 0x45, 0x48, 0x68, 0x31, 0x57, 0x47, 0x5A, 0x6D,
43 0x36, 0x77, 0x64, 0x2B, 0x4B, 0x76, 0x38, 0x6B, 0x31, 0x6B, 0x2F, 0x36, 0x6F, 0x41, 0x2F, 0x4F,
44 0x51, 0x76, 0x65, 0x61, 0x38, 0x6B, 0x63, 0x45, 0x64, 0x53, 0x72, 0x54, 0x64, 0x75, 0x71, 0x4A,
45 0x33, 0x65, 0x66, 0x74, 0x48, 0x4A, 0x4A, 0x6E, 0x43, 0x4B, 0x30, 0x41, 0x62, 0x68, 0x34, 0x39,
46 0x0A, 0x41, 0x47, 0x41, 0x50, 0x39, 0x79, 0x58, 0x77, 0x77, 0x59, 0x41, 0x6A, 0x51, 0x49, 0x52,
47 0x6E, 0x38, 0x2B, 0x4F, 0x63, 0x63, 0x48, 0x74, 0x6F, 0x4E, 0x75, 0x75, 0x79, 0x52, 0x63, 0x6B,
48 0x49, 0x50, 0x71, 0x75, 0x70, 0x78, 0x79, 0x31, 0x4A, 0x5A, 0x4B, 0x39, 0x64, 0x76, 0x76, 0x62,
49 0x34, 0x79, 0x53, 0x6B, 0x49, 0x75, 0x7A, 0x62, 0x79, 0x50, 0x6F, 0x54, 0x41, 0x79, 0x61, 0x55,
50 0x2B, 0x0A, 0x51, 0x72, 0x70, 0x34, 0x78, 0x67, 0x64, 0x4B, 0x46, 0x54, 0x70, 0x6B, 0x50, 0x46,
51 0x34, 0x33, 0x6A, 0x32, 0x4D, 0x6D, 0x5A, 0x72, 0x46, 0x63, 0x42, 0x76, 0x79, 0x6A, 0x69, 0x35,
52 0x6A, 0x4F, 0x37, 0x74, 0x66, 0x6F, 0x56, 0x61, 0x6B, 0x59, 0x47, 0x53, 0x2F, 0x4C, 0x63, 0x78,
53 0x77, 0x47, 0x2B, 0x77, 0x51, 0x77, 0x63, 0x4F, 0x43, 0x54, 0x42, 0x45, 0x78, 0x2F, 0x7A, 0x31,
54 0x53, 0x30, 0x0A, 0x37, 0x49, 0x2F, 0x6A, 0x62, 0x44, 0x79, 0x53, 0x4E, 0x68, 0x44, 0x35, 0x63,
55 0x61, 0x63, 0x54, 0x75, 0x4E, 0x36, 0x50, 0x68, 0x33, 0x58, 0x30, 0x71, 0x70, 0x47, 0x73, 0x37,
56 0x79, 0x50, 0x6B, 0x4E, 0x79, 0x69, 0x4A, 0x33, 0x57, 0x52, 0x69, 0x6C, 0x35, 0x75, 0x57, 0x73,
57 0x4B, 0x65, 0x79, 0x63, 0x64, 0x71, 0x42, 0x4E, 0x72, 0x34, 0x75, 0x32, 0x62, 0x49, 0x52, 0x6E,
58 0x63, 0x54, 0x51, 0x0A, 0x46, 0x72, 0x68, 0x73, 0x58, 0x39, 0x69, 0x77, 0x37, 0x35, 0x76, 0x75,
59 0x53, 0x64, 0x35, 0x46, 0x39, 0x37, 0x56, 0x70, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41, 0x47, 0x6A,
60 0x4A, 0x44, 0x41, 0x69, 0x4D, 0x42, 0x4D, 0x47, 0x41, 0x31, 0x55, 0x64, 0x4A, 0x51, 0x51, 0x4D,
61 0x4D, 0x41, 0x6F, 0x47, 0x43, 0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42, 0x77, 0x4D, 0x42,
62 0x4D, 0x41, 0x73, 0x47, 0x0A, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x51, 0x45, 0x41, 0x77, 0x49,
63 0x45, 0x4D, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47, 0x39, 0x77, 0x30,
64 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4F, 0x43, 0x41, 0x51, 0x45, 0x41, 0x49, 0x51, 0x66,
65 0x75, 0x2F, 0x77, 0x39, 0x45, 0x34, 0x4C, 0x6F, 0x67, 0x30, 0x71, 0x35, 0x4B, 0x53, 0x38, 0x71,
66 0x46, 0x78, 0x62, 0x36, 0x6F, 0x0A, 0x36, 0x31, 0x62, 0x35, 0x37, 0x6F, 0x6D, 0x6E, 0x46, 0x59,
67 0x52, 0x34, 0x47, 0x43, 0x67, 0x33, 0x6F, 0x6A, 0x4F, 0x4C, 0x54, 0x66, 0x38, 0x7A, 0x6A, 0x4D,
68 0x43, 0x52, 0x6D, 0x75, 0x59, 0x32, 0x76, 0x30, 0x4E, 0x34, 0x78, 0x66, 0x68, 0x69, 0x35, 0x4B,
69 0x69, 0x59, 0x67, 0x64, 0x76, 0x4E, 0x4C, 0x4F, 0x33, 0x52, 0x42, 0x6D, 0x4E, 0x50, 0x76, 0x59,
70 0x58, 0x50, 0x52, 0x46, 0x41, 0x76, 0x0A, 0x66, 0x61, 0x76, 0x66, 0x57, 0x75, 0x6C, 0x44, 0x31,
71 0x64, 0x50, 0x36, 0x31, 0x69, 0x35, 0x62, 0x36, 0x59, 0x66, 0x56, 0x6C, 0x78, 0x62, 0x31, 0x61,
72 0x57, 0x46, 0x37, 0x4C, 0x5A, 0x44, 0x32, 0x55, 0x6E, 0x63, 0x41, 0x6A, 0x37, 0x4E, 0x38, 0x78,
73 0x38, 0x2B, 0x36, 0x58, 0x6B, 0x30, 0x6B, 0x63, 0x70, 0x58, 0x46, 0x38, 0x6C, 0x77, 0x58, 0x48,
74 0x55, 0x57, 0x57, 0x55, 0x6D, 0x73, 0x2B, 0x0A, 0x4B, 0x56, 0x44, 0x34, 0x34, 0x39, 0x68, 0x6F,
75 0x4D, 0x2B, 0x77, 0x4E, 0x4A, 0x49, 0x61, 0x4F, 0x52, 0x39, 0x4C, 0x46, 0x2B, 0x6B, 0x6F, 0x32,
76 0x32, 0x37, 0x7A, 0x74, 0x37, 0x54, 0x41, 0x47, 0x64, 0x56, 0x35, 0x4A, 0x75, 0x7A, 0x71, 0x38,
77 0x32, 0x2F, 0x6B, 0x75, 0x73, 0x6F, 0x65, 0x32, 0x69, 0x75, 0x57, 0x77, 0x54, 0x65, 0x42, 0x6C,
78 0x53, 0x5A, 0x6E, 0x6B, 0x42, 0x38, 0x63, 0x64, 0x0A, 0x77, 0x4D, 0x30, 0x5A, 0x42, 0x58, 0x6D,
79 0x34, 0x35, 0x48, 0x38, 0x6F, 0x79, 0x75, 0x36, 0x4A, 0x71, 0x59, 0x71, 0x45, 0x6D, 0x75, 0x4A,
80 0x51, 0x64, 0x67, 0x79, 0x52, 0x2B, 0x63, 0x53, 0x53, 0x41, 0x7A, 0x2B, 0x4F, 0x32, 0x6D, 0x61,
81 0x62, 0x68, 0x50, 0x5A, 0x65, 0x49, 0x76, 0x78, 0x65, 0x67, 0x6A, 0x6A, 0x61, 0x5A, 0x61, 0x46,
82 0x4F, 0x71, 0x74, 0x73, 0x2B, 0x64, 0x33, 0x72, 0x39, 0x0A, 0x79, 0x71, 0x4A, 0x78, 0x67, 0x75,
83 0x39, 0x43, 0x38, 0x39, 0x5A, 0x69, 0x33, 0x39, 0x57, 0x34, 0x38, 0x46, 0x66, 0x46, 0x63, 0x49,
84 0x58, 0x4A, 0x4F, 0x6B, 0x39, 0x43, 0x4E, 0x46, 0x41, 0x2F, 0x69, 0x70, 0x54, 0x57, 0x6A, 0x74,
85 0x74, 0x4E, 0x2F, 0x6B, 0x4F, 0x6B, 0x5A, 0x42, 0x70, 0x6F, 0x6A, 0x2F, 0x32, 0x6A, 0x4E, 0x45,
86 0x62, 0x4F, 0x59, 0x7A, 0x7A, 0x6E, 0x4B, 0x77, 0x3D, 0x3D, 0x0A, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D,
87 0x45, 0x4E, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2D,
88 0x2D, 0x2D, 0x2D, 0x2D, 0x0A
89};
90
91static const BYTE test_localhost_key[1704] = {
92 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x42, 0x45, 0x47, 0x49, 0x4E, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41,
93 0x54, 0x45, 0x20, 0x4B, 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A, 0x4D, 0x49, 0x49, 0x45,
94 0x76, 0x51, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4E, 0x42, 0x67, 0x6B, 0x71, 0x68, 0x6B, 0x69, 0x47,
95 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43, 0x42, 0x4B, 0x63, 0x77,
96 0x67, 0x67, 0x53, 0x6A, 0x41, 0x67, 0x45, 0x41, 0x41, 0x6F, 0x49, 0x42, 0x41, 0x51, 0x43, 0x33,
97 0x65, 0x6E, 0x33, 0x68, 0x5A, 0x4F, 0x53, 0x33, 0x6B, 0x51, 0x2F, 0x55, 0x0A, 0x54, 0x30, 0x53,
98 0x45, 0x6C, 0x30, 0x48, 0x6E, 0x50, 0x79, 0x64, 0x48, 0x75, 0x35, 0x39, 0x61, 0x69, 0x71, 0x64,
99 0x73, 0x64, 0x53, 0x55, 0x74, 0x6E, 0x43, 0x41, 0x37, 0x46, 0x66, 0x74, 0x30, 0x4F, 0x36, 0x51,
100 0x79, 0x68, 0x49, 0x71, 0x58, 0x7A, 0x30, 0x47, 0x32, 0x53, 0x76, 0x77, 0x4C, 0x54, 0x62, 0x79,
101 0x68, 0x59, 0x54, 0x68, 0x31, 0x36, 0x78, 0x31, 0x72, 0x45, 0x48, 0x68, 0x31, 0x0A, 0x57, 0x47,
102 0x5A, 0x6D, 0x36, 0x77, 0x64, 0x2B, 0x4B, 0x76, 0x38, 0x6B, 0x31, 0x6B, 0x2F, 0x36, 0x6F, 0x41,
103 0x2F, 0x4F, 0x51, 0x76, 0x65, 0x61, 0x38, 0x6B, 0x63, 0x45, 0x64, 0x53, 0x72, 0x54, 0x64, 0x75,
104 0x71, 0x4A, 0x33, 0x65, 0x66, 0x74, 0x48, 0x4A, 0x4A, 0x6E, 0x43, 0x4B, 0x30, 0x41, 0x62, 0x68,
105 0x34, 0x39, 0x41, 0x47, 0x41, 0x50, 0x39, 0x79, 0x58, 0x77, 0x77, 0x59, 0x41, 0x6A, 0x0A, 0x51,
106 0x49, 0x52, 0x6E, 0x38, 0x2B, 0x4F, 0x63, 0x63, 0x48, 0x74, 0x6F, 0x4E, 0x75, 0x75, 0x79, 0x52,
107 0x63, 0x6B, 0x49, 0x50, 0x71, 0x75, 0x70, 0x78, 0x79, 0x31, 0x4A, 0x5A, 0x4B, 0x39, 0x64, 0x76,
108 0x76, 0x62, 0x34, 0x79, 0x53, 0x6B, 0x49, 0x75, 0x7A, 0x62, 0x79, 0x50, 0x6F, 0x54, 0x41, 0x79,
109 0x61, 0x55, 0x2B, 0x51, 0x72, 0x70, 0x34, 0x78, 0x67, 0x64, 0x4B, 0x46, 0x54, 0x70, 0x6B, 0x0A,
110 0x50, 0x46, 0x34, 0x33, 0x6A, 0x32, 0x4D, 0x6D, 0x5A, 0x72, 0x46, 0x63, 0x42, 0x76, 0x79, 0x6A,
111 0x69, 0x35, 0x6A, 0x4F, 0x37, 0x74, 0x66, 0x6F, 0x56, 0x61, 0x6B, 0x59, 0x47, 0x53, 0x2F, 0x4C,
112 0x63, 0x78, 0x77, 0x47, 0x2B, 0x77, 0x51, 0x77, 0x63, 0x4F, 0x43, 0x54, 0x42, 0x45, 0x78, 0x2F,
113 0x7A, 0x31, 0x53, 0x30, 0x37, 0x49, 0x2F, 0x6A, 0x62, 0x44, 0x79, 0x53, 0x4E, 0x68, 0x44, 0x35,
114 0x0A, 0x63, 0x61, 0x63, 0x54, 0x75, 0x4E, 0x36, 0x50, 0x68, 0x33, 0x58, 0x30, 0x71, 0x70, 0x47,
115 0x73, 0x37, 0x79, 0x50, 0x6B, 0x4E, 0x79, 0x69, 0x4A, 0x33, 0x57, 0x52, 0x69, 0x6C, 0x35, 0x75,
116 0x57, 0x73, 0x4B, 0x65, 0x79, 0x63, 0x64, 0x71, 0x42, 0x4E, 0x72, 0x34, 0x75, 0x32, 0x62, 0x49,
117 0x52, 0x6E, 0x63, 0x54, 0x51, 0x46, 0x72, 0x68, 0x73, 0x58, 0x39, 0x69, 0x77, 0x37, 0x35, 0x76,
118 0x75, 0x0A, 0x53, 0x64, 0x35, 0x46, 0x39, 0x37, 0x56, 0x70, 0x41, 0x67, 0x4D, 0x42, 0x41, 0x41,
119 0x45, 0x43, 0x67, 0x67, 0x45, 0x41, 0x42, 0x36, 0x6A, 0x6C, 0x65, 0x48, 0x4E, 0x74, 0x32, 0x50,
120 0x77, 0x46, 0x58, 0x53, 0x65, 0x79, 0x42, 0x4A, 0x63, 0x4C, 0x2B, 0x55, 0x74, 0x35, 0x71, 0x46,
121 0x54, 0x38, 0x34, 0x68, 0x72, 0x48, 0x77, 0x6F, 0x39, 0x68, 0x62, 0x66, 0x59, 0x47, 0x6F, 0x6E,
122 0x44, 0x59, 0x0A, 0x66, 0x70, 0x47, 0x2B, 0x32, 0x52, 0x30, 0x50, 0x62, 0x43, 0x63, 0x4B, 0x35,
123 0x30, 0x46, 0x61, 0x4A, 0x46, 0x36, 0x71, 0x63, 0x56, 0x4A, 0x4E, 0x75, 0x52, 0x36, 0x48, 0x71,
124 0x2B, 0x43, 0x55, 0x4A, 0x74, 0x48, 0x35, 0x39, 0x48, 0x48, 0x37, 0x62, 0x68, 0x6A, 0x39, 0x62,
125 0x64, 0x78, 0x45, 0x6D, 0x6F, 0x48, 0x30, 0x4A, 0x76, 0x68, 0x45, 0x76, 0x67, 0x4D, 0x2F, 0x55,
126 0x38, 0x42, 0x51, 0x0A, 0x65, 0x57, 0x4F, 0x4E, 0x68, 0x78, 0x50, 0x73, 0x69, 0x73, 0x6D, 0x57,
127 0x6B, 0x78, 0x61, 0x5A, 0x6F, 0x6C, 0x72, 0x32, 0x69, 0x44, 0x56, 0x72, 0x7A, 0x54, 0x37, 0x55,
128 0x4A, 0x71, 0x6A, 0x74, 0x59, 0x49, 0x74, 0x67, 0x2B, 0x37, 0x59, 0x43, 0x32, 0x70, 0x55, 0x58,
129 0x6B, 0x64, 0x49, 0x35, 0x4A, 0x4D, 0x67, 0x6C, 0x44, 0x47, 0x4D, 0x52, 0x5A, 0x35, 0x55, 0x5A,
130 0x48, 0x75, 0x63, 0x7A, 0x0A, 0x41, 0x56, 0x2B, 0x71, 0x77, 0x77, 0x33, 0x65, 0x45, 0x52, 0x74,
131 0x78, 0x44, 0x50, 0x61, 0x61, 0x61, 0x34, 0x54, 0x39, 0x50, 0x64, 0x33, 0x44, 0x31, 0x6D, 0x62,
132 0x71, 0x58, 0x66, 0x75, 0x45, 0x68, 0x42, 0x6D, 0x33, 0x51, 0x6F, 0x2B, 0x75, 0x7A, 0x51, 0x32,
133 0x36, 0x76, 0x73, 0x66, 0x48, 0x75, 0x56, 0x76, 0x61, 0x39, 0x38, 0x32, 0x4F, 0x6A, 0x41, 0x55,
134 0x6A, 0x6E, 0x64, 0x30, 0x70, 0x0A, 0x77, 0x43, 0x53, 0x6E, 0x42, 0x49, 0x48, 0x67, 0x70, 0x73,
135 0x30, 0x79, 0x61, 0x45, 0x50, 0x63, 0x37, 0x46, 0x78, 0x39, 0x71, 0x45, 0x63, 0x6D, 0x33, 0x70,
136 0x7A, 0x41, 0x56, 0x31, 0x69, 0x72, 0x31, 0x4E, 0x4E, 0x63, 0x51, 0x47, 0x55, 0x45, 0x75, 0x45,
137 0x6C, 0x4A, 0x78, 0x76, 0x2B, 0x69, 0x57, 0x34, 0x6D, 0x35, 0x70, 0x7A, 0x4C, 0x6A, 0x64, 0x53,
138 0x63, 0x49, 0x30, 0x59, 0x45, 0x73, 0x0A, 0x4D, 0x61, 0x33, 0x78, 0x32, 0x79, 0x48, 0x74, 0x6E,
139 0x77, 0x79, 0x65, 0x4C, 0x4D, 0x54, 0x4B, 0x6C, 0x72, 0x46, 0x4B, 0x70, 0x55, 0x4E, 0x4A, 0x62,
140 0x78, 0x73, 0x35, 0x32, 0x62, 0x5A, 0x4B, 0x71, 0x49, 0x56, 0x33, 0x33, 0x4A, 0x53, 0x34, 0x41,
141 0x51, 0x4B, 0x42, 0x67, 0x51, 0x44, 0x73, 0x4C, 0x54, 0x49, 0x68, 0x35, 0x59, 0x38, 0x4C, 0x2F,
142 0x48, 0x33, 0x64, 0x74, 0x68, 0x63, 0x62, 0x0A, 0x53, 0x43, 0x45, 0x77, 0x32, 0x64, 0x42, 0x49,
143 0x76, 0x49, 0x79, 0x54, 0x7A, 0x39, 0x53, 0x72, 0x62, 0x33, 0x58, 0x37, 0x37, 0x41, 0x77, 0x57,
144 0x45, 0x4C, 0x53, 0x4D, 0x49, 0x57, 0x53, 0x50, 0x55, 0x43, 0x4B, 0x54, 0x49, 0x70, 0x6A, 0x4D,
145 0x73, 0x6E, 0x7A, 0x6B, 0x46, 0x67, 0x32, 0x32, 0x59, 0x32, 0x53, 0x75, 0x47, 0x38, 0x4C, 0x72,
146 0x50, 0x6D, 0x76, 0x73, 0x46, 0x4A, 0x34, 0x30, 0x0A, 0x32, 0x67, 0x35, 0x44, 0x55, 0x6C, 0x59,
147 0x33, 0x59, 0x6D, 0x53, 0x4F, 0x46, 0x61, 0x45, 0x4A, 0x54, 0x70, 0x55, 0x47, 0x44, 0x4D, 0x79,
148 0x65, 0x33, 0x74, 0x36, 0x4F, 0x30, 0x6C, 0x63, 0x51, 0x41, 0x66, 0x79, 0x6D, 0x58, 0x66, 0x41,
149 0x38, 0x74, 0x50, 0x42, 0x48, 0x6A, 0x5A, 0x78, 0x56, 0x61, 0x38, 0x78, 0x78, 0x52, 0x5A, 0x6E,
150 0x56, 0x43, 0x31, 0x41, 0x62, 0x75, 0x49, 0x49, 0x52, 0x0A, 0x6E, 0x77, 0x72, 0x4E, 0x46, 0x2B,
151 0x42, 0x6F, 0x53, 0x4B, 0x55, 0x41, 0x73, 0x78, 0x2B, 0x46, 0x75, 0x35, 0x5A, 0x4A, 0x4B, 0x4F,
152 0x66, 0x79, 0x4D, 0x51, 0x4B, 0x42, 0x67, 0x51, 0x44, 0x47, 0x34, 0x50, 0x52, 0x39, 0x2F, 0x58,
153 0x58, 0x6B, 0x51, 0x54, 0x36, 0x6B, 0x7A, 0x4B, 0x64, 0x34, 0x50, 0x6C, 0x50, 0x4D, 0x63, 0x2B,
154 0x4B, 0x51, 0x79, 0x4C, 0x45, 0x6C, 0x4B, 0x39, 0x71, 0x47, 0x0A, 0x41, 0x6D, 0x6E, 0x2F, 0x31,
155 0x68, 0x64, 0x69, 0x57, 0x57, 0x4F, 0x52, 0x57, 0x46, 0x62, 0x32, 0x38, 0x30, 0x4D, 0x77, 0x76,
156 0x77, 0x41, 0x64, 0x78, 0x72, 0x66, 0x65, 0x4C, 0x57, 0x4D, 0x57, 0x32, 0x66, 0x76, 0x4C, 0x59,
157 0x4B, 0x66, 0x6C, 0x4F, 0x35, 0x50, 0x51, 0x44, 0x59, 0x67, 0x4B, 0x4A, 0x78, 0x35, 0x79, 0x50,
158 0x37, 0x52, 0x64, 0x38, 0x2F, 0x64, 0x50, 0x79, 0x5A, 0x59, 0x36, 0x0A, 0x7A, 0x56, 0x37, 0x47,
159 0x47, 0x6B, 0x51, 0x5A, 0x42, 0x4B, 0x36, 0x79, 0x74, 0x61, 0x66, 0x32, 0x35, 0x44, 0x50, 0x67,
160 0x50, 0x72, 0x32, 0x77, 0x73, 0x59, 0x4D, 0x43, 0x6C, 0x53, 0x74, 0x6C, 0x56, 0x74, 0x72, 0x6D,
161 0x4F, 0x78, 0x59, 0x55, 0x56, 0x77, 0x42, 0x59, 0x4F, 0x69, 0x36, 0x45, 0x62, 0x50, 0x69, 0x6B,
162 0x78, 0x47, 0x48, 0x5A, 0x70, 0x59, 0x6F, 0x5A, 0x5A, 0x70, 0x68, 0x4A, 0x0A, 0x4E, 0x61, 0x38,
163 0x4F, 0x4C, 0x31, 0x69, 0x77, 0x75, 0x51, 0x4B, 0x42, 0x67, 0x51, 0x44, 0x42, 0x55, 0x55, 0x31,
164 0x54, 0x79, 0x5A, 0x2B, 0x4A, 0x5A, 0x43, 0x64, 0x79, 0x72, 0x33, 0x58, 0x43, 0x63, 0x77, 0x77,
165 0x58, 0x2F, 0x48, 0x49, 0x73, 0x31, 0x34, 0x6B, 0x4B, 0x42, 0x48, 0x68, 0x44, 0x79, 0x33, 0x78,
166 0x37, 0x74, 0x50, 0x38, 0x2F, 0x6F, 0x48, 0x54, 0x6F, 0x72, 0x76, 0x79, 0x74, 0x0A, 0x41, 0x68,
167 0x38, 0x4B, 0x36, 0x4B, 0x72, 0x43, 0x41, 0x75, 0x65, 0x50, 0x6D, 0x79, 0x32, 0x6D, 0x4F, 0x54,
168 0x31, 0x54, 0x39, 0x6F, 0x31, 0x61, 0x47, 0x55, 0x49, 0x6C, 0x66, 0x38, 0x72, 0x76, 0x33, 0x2F,
169 0x30, 0x45, 0x78, 0x67, 0x53, 0x6B, 0x57, 0x50, 0x6D, 0x4F, 0x41, 0x38, 0x35, 0x49, 0x32, 0x2F,
170 0x58, 0x48, 0x65, 0x66, 0x71, 0x54, 0x6F, 0x45, 0x48, 0x30, 0x44, 0x65, 0x41, 0x4E, 0x0A, 0x7A,
171 0x6C, 0x4B, 0x4C, 0x71, 0x79, 0x44, 0x56, 0x30, 0x42, 0x56, 0x4E, 0x76, 0x48, 0x42, 0x57, 0x79,
172 0x32, 0x49, 0x51, 0x35, 0x62, 0x50, 0x42, 0x57, 0x76, 0x30, 0x37, 0x63, 0x34, 0x2B, 0x6A, 0x39,
173 0x4E, 0x62, 0x57, 0x67, 0x64, 0x44, 0x43, 0x43, 0x35, 0x52, 0x6B, 0x4F, 0x6A, 0x70, 0x33, 0x4D,
174 0x4E, 0x45, 0x58, 0x47, 0x56, 0x43, 0x69, 0x51, 0x51, 0x4B, 0x42, 0x67, 0x43, 0x7A, 0x4D, 0x0A,
175 0x77, 0x65, 0x61, 0x62, 0x73, 0x50, 0x48, 0x68, 0x44, 0x4B, 0x5A, 0x38, 0x2F, 0x34, 0x43, 0x6A,
176 0x73, 0x61, 0x62, 0x4E, 0x75, 0x41, 0x7A, 0x62, 0x57, 0x4B, 0x52, 0x42, 0x38, 0x37, 0x44, 0x61,
177 0x58, 0x46, 0x78, 0x6F, 0x4D, 0x73, 0x35, 0x52, 0x79, 0x6F, 0x38, 0x55, 0x4D, 0x6B, 0x72, 0x67,
178 0x30, 0x35, 0x4C, 0x6F, 0x67, 0x37, 0x4D, 0x78, 0x62, 0x33, 0x76, 0x61, 0x42, 0x34, 0x63, 0x2F,
179 0x0A, 0x52, 0x57, 0x77, 0x7A, 0x38, 0x72, 0x34, 0x39, 0x70, 0x48, 0x64, 0x71, 0x68, 0x4F, 0x6D,
180 0x63, 0x6C, 0x45, 0x77, 0x79, 0x4D, 0x34, 0x51, 0x79, 0x6A, 0x39, 0x52, 0x6D, 0x57, 0x62, 0x51,
181 0x58, 0x54, 0x54, 0x45, 0x63, 0x2B, 0x35, 0x67, 0x54, 0x4B, 0x50, 0x4E, 0x53, 0x33, 0x6D, 0x70,
182 0x4D, 0x54, 0x36, 0x39, 0x46, 0x45, 0x74, 0x2F, 0x35, 0x72, 0x4D, 0x52, 0x70, 0x4B, 0x2B, 0x52,
183 0x68, 0x0A, 0x49, 0x32, 0x42, 0x58, 0x6B, 0x51, 0x71, 0x31, 0x36, 0x6E, 0x72, 0x31, 0x61, 0x45,
184 0x4D, 0x6D, 0x64, 0x51, 0x42, 0x51, 0x79, 0x4B, 0x59, 0x4A, 0x6C, 0x30, 0x6C, 0x50, 0x68, 0x69,
185 0x42, 0x2F, 0x75, 0x6C, 0x5A, 0x63, 0x72, 0x67, 0x4C, 0x70, 0x41, 0x6F, 0x47, 0x41, 0x65, 0x30,
186 0x65, 0x74, 0x50, 0x4A, 0x77, 0x6D, 0x51, 0x46, 0x6B, 0x6A, 0x4D, 0x70, 0x66, 0x4D, 0x44, 0x61,
187 0x4E, 0x34, 0x0A, 0x70, 0x7A, 0x71, 0x45, 0x51, 0x72, 0x52, 0x35, 0x4B, 0x35, 0x4D, 0x6E, 0x54,
188 0x48, 0x76, 0x47, 0x67, 0x2F, 0x70, 0x6A, 0x57, 0x6A, 0x43, 0x57, 0x58, 0x56, 0x48, 0x67, 0x35,
189 0x76, 0x36, 0x46, 0x6F, 0x5A, 0x48, 0x35, 0x6E, 0x59, 0x2B, 0x56, 0x2F, 0x57, 0x75, 0x57, 0x38,
190 0x38, 0x6A, 0x6C, 0x4B, 0x53, 0x50, 0x6C, 0x77, 0x6A, 0x50, 0x7A, 0x41, 0x67, 0x7A, 0x47, 0x33,
191 0x45, 0x41, 0x55, 0x0A, 0x71, 0x57, 0x6B, 0x42, 0x67, 0x30, 0x71, 0x75, 0x50, 0x4D, 0x72, 0x54,
192 0x6B, 0x73, 0x69, 0x6E, 0x58, 0x50, 0x2B, 0x58, 0x6B, 0x51, 0x65, 0x46, 0x66, 0x58, 0x61, 0x33,
193 0x38, 0x6A, 0x72, 0x70, 0x62, 0x4B, 0x46, 0x4F, 0x72, 0x7A, 0x49, 0x6F, 0x6A, 0x69, 0x65, 0x6C,
194 0x4B, 0x55, 0x4D, 0x50, 0x4D, 0x78, 0x2F, 0x78, 0x70, 0x53, 0x6A, 0x63, 0x55, 0x42, 0x68, 0x62,
195 0x4E, 0x34, 0x45, 0x54, 0x0A, 0x4F, 0x30, 0x66, 0x63, 0x57, 0x47, 0x6F, 0x61, 0x56, 0x50, 0x72,
196 0x63, 0x6E, 0x38, 0x62, 0x58, 0x4D, 0x54, 0x45, 0x4E, 0x53, 0x31, 0x41, 0x3D, 0x0A, 0x2D, 0x2D,
197 0x2D, 0x2D, 0x2D, 0x45, 0x4E, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4B,
198 0x45, 0x59, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x0A
199};
200
201static const BYTE test_DummyMessage[64] = {
202 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
203 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB,
204 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
205 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD
206};
207
208static const BYTE test_LastDummyMessage[64] = {
209 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
213};
214
215static int schannel_send(PSecurityFunctionTable table, HANDLE hPipe, PCtxtHandle phContext,
216 BYTE* buffer, UINT32 length)
217{
218 BYTE* ioBuffer;
219 UINT32 ioBufferLength;
220 BYTE* pMessageBuffer;
221 SecBuffer Buffers[4] = { 0 };
222 SecBufferDesc Message;
223 SECURITY_STATUS status;
224 DWORD NumberOfBytesWritten;
225 SecPkgContext_StreamSizes StreamSizes = { 0 };
226
227 status = table->QueryContextAttributes(phContext, SECPKG_ATTR_STREAM_SIZES, &StreamSizes);
228 ioBufferLength = StreamSizes.cbHeader + StreamSizes.cbMaximumMessage + StreamSizes.cbTrailer;
229 ioBuffer = (BYTE*)calloc(1, ioBufferLength);
230 if (!ioBuffer)
231 return -1;
232 pMessageBuffer = ioBuffer + StreamSizes.cbHeader;
233 CopyMemory(pMessageBuffer, buffer, length);
234 Buffers[0].pvBuffer = ioBuffer;
235 Buffers[0].cbBuffer = StreamSizes.cbHeader;
236 Buffers[0].BufferType = SECBUFFER_STREAM_HEADER;
237 Buffers[1].pvBuffer = pMessageBuffer;
238 Buffers[1].cbBuffer = length;
239 Buffers[1].BufferType = SECBUFFER_DATA;
240 Buffers[2].pvBuffer = pMessageBuffer + length;
241 Buffers[2].cbBuffer = StreamSizes.cbTrailer;
242 Buffers[2].BufferType = SECBUFFER_STREAM_TRAILER;
243 Buffers[3].pvBuffer = NULL;
244 Buffers[3].cbBuffer = 0;
245 Buffers[3].BufferType = SECBUFFER_EMPTY;
246 Message.ulVersion = SECBUFFER_VERSION;
247 Message.cBuffers = 4;
248 Message.pBuffers = Buffers;
249 ioBufferLength =
250 Message.pBuffers[0].cbBuffer + Message.pBuffers[1].cbBuffer + Message.pBuffers[2].cbBuffer;
251 status = table->EncryptMessage(phContext, 0, &Message, 0);
252 printf("EncryptMessage status: 0x%08" PRIX32 "\n", status);
253 printf("EncryptMessage output: cBuffers: %" PRIu32 " [0]: %" PRIu32 " / %" PRIu32
254 " [1]: %" PRIu32 " / %" PRIu32 " [2]: %" PRIu32 " / %" PRIu32 " [3]: %" PRIu32
255 " / %" PRIu32 "\n",
256 Message.cBuffers, Message.pBuffers[0].cbBuffer, Message.pBuffers[0].BufferType,
257 Message.pBuffers[1].cbBuffer, Message.pBuffers[1].BufferType,
258 Message.pBuffers[2].cbBuffer, Message.pBuffers[2].BufferType,
259 Message.pBuffers[3].cbBuffer, Message.pBuffers[3].BufferType);
260
261 if (status != SEC_E_OK)
262 return -1;
263
264 printf("Client > Server (%" PRIu32 ")\n", ioBufferLength);
265 winpr_HexDump("sspi.test", WLOG_DEBUG, ioBuffer, ioBufferLength);
266
267 if (!WriteFile(hPipe, ioBuffer, ioBufferLength, &NumberOfBytesWritten, NULL))
268 {
269 printf("schannel_send: failed to write to pipe\n");
270 return -1;
271 }
272
273 return 0;
274}
275
276static int schannel_recv(PSecurityFunctionTable table, HANDLE hPipe, PCtxtHandle phContext)
277{
278 BYTE* ioBuffer;
279 UINT32 ioBufferLength;
280 // BYTE* pMessageBuffer;
281 SecBuffer Buffers[4] = { 0 };
282 SecBufferDesc Message;
283 SECURITY_STATUS status;
284 DWORD NumberOfBytesRead;
285 SecPkgContext_StreamSizes StreamSizes = { 0 };
286
287 status = table->QueryContextAttributes(phContext, SECPKG_ATTR_STREAM_SIZES, &StreamSizes);
288 ioBufferLength = StreamSizes.cbHeader + StreamSizes.cbMaximumMessage + StreamSizes.cbTrailer;
289 ioBuffer = (BYTE*)calloc(1, ioBufferLength);
290 if (!ioBuffer)
291 return -1;
292
293 if (!ReadFile(hPipe, ioBuffer, ioBufferLength, &NumberOfBytesRead, NULL))
294 {
295 printf("schannel_recv: failed to read from pipe\n");
296 return -1;
297 }
298
299 Buffers[0].pvBuffer = ioBuffer;
300 Buffers[0].cbBuffer = NumberOfBytesRead;
301 Buffers[0].BufferType = SECBUFFER_DATA;
302 Buffers[1].pvBuffer = NULL;
303 Buffers[1].cbBuffer = 0;
304 Buffers[1].BufferType = SECBUFFER_EMPTY;
305 Buffers[2].pvBuffer = NULL;
306 Buffers[2].cbBuffer = 0;
307 Buffers[2].BufferType = SECBUFFER_EMPTY;
308 Buffers[3].pvBuffer = NULL;
309 Buffers[3].cbBuffer = 0;
310 Buffers[3].BufferType = SECBUFFER_EMPTY;
311 Message.ulVersion = SECBUFFER_VERSION;
312 Message.cBuffers = 4;
313 Message.pBuffers = Buffers;
314 status = table->DecryptMessage(phContext, &Message, 0, NULL);
315 printf("DecryptMessage status: 0x%08" PRIX32 "\n", status);
316 printf("DecryptMessage output: cBuffers: %" PRIu32 " [0]: %" PRIu32 " / %" PRIu32
317 " [1]: %" PRIu32 " / %" PRIu32 " [2]: %" PRIu32 " / %" PRIu32 " [3]: %" PRIu32
318 " / %" PRIu32 "\n",
319 Message.cBuffers, Message.pBuffers[0].cbBuffer, Message.pBuffers[0].BufferType,
320 Message.pBuffers[1].cbBuffer, Message.pBuffers[1].BufferType,
321 Message.pBuffers[2].cbBuffer, Message.pBuffers[2].BufferType,
322 Message.pBuffers[3].cbBuffer, Message.pBuffers[3].BufferType);
323
324 if (status != SEC_E_OK)
325 return -1;
326
327 printf("Decrypted Message (%" PRIu32 ")\n", Message.pBuffers[1].cbBuffer);
328 winpr_HexDump("sspi.test", WLOG_DEBUG, (BYTE*)Message.pBuffers[1].pvBuffer,
329 Message.pBuffers[1].cbBuffer);
330
331 if (memcmp(Message.pBuffers[1].pvBuffer, test_LastDummyMessage,
332 sizeof(test_LastDummyMessage)) == 0)
333 return -1;
334
335 return 0;
336}
337
338static DWORD WINAPI schannel_test_server_thread(LPVOID arg)
339{
340 BOOL extraData;
341 BYTE* lpTokenIn;
342 BYTE* lpTokenOut;
343 TimeStamp expiry;
344 UINT32 cbMaxToken;
345 UINT32 fContextReq;
346 ULONG fContextAttr;
347 SCHANNEL_CRED cred = { 0 };
348 CtxtHandle context;
349 CredHandle credentials;
350 DWORD cchNameString;
351 LPTSTR pszNameString;
352 HCERTSTORE hCertStore;
353 PCCERT_CONTEXT pCertContext;
354 PSecBuffer pSecBuffer;
355 SecBuffer SecBuffer_in[2] = { 0 };
356 SecBuffer SecBuffer_out[2] = { 0 };
357 SecBufferDesc SecBufferDesc_in;
358 SecBufferDesc SecBufferDesc_out;
359 DWORD NumberOfBytesRead;
360 SECURITY_STATUS status;
361 PSecPkgInfo pPackageInfo;
362 PSecurityFunctionTable table;
363 DWORD NumberOfBytesWritten;
364 printf("Starting Server\n");
365 SecInvalidateHandle(&context);
366 SecInvalidateHandle(&credentials);
367 table = InitSecurityInterface();
368 status = QuerySecurityPackageInfo(SCHANNEL_NAME, &pPackageInfo);
369
370 if (status != SEC_E_OK)
371 {
372 printf("QuerySecurityPackageInfo failure: 0x%08" PRIX32 "\n", status);
373 return 0;
374 }
375
376 cbMaxToken = pPackageInfo->cbMaxToken;
377 hCertStore = CertOpenSystemStore(0, _T("MY"));
378
379 if (!hCertStore)
380 {
381 printf("Error opening system store\n");
382 // return NULL;
383 }
384
385#ifdef CERT_FIND_HAS_PRIVATE_KEY
386 pCertContext = CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING, 0,
387 CERT_FIND_HAS_PRIVATE_KEY, NULL, NULL);
388#else
389 pCertContext =
390 CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL);
391#endif
392
393 if (!pCertContext)
394 {
395 printf("Error finding certificate in store\n");
396 // return NULL;
397 }
398
399 cchNameString =
400 CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0);
401 pszNameString = (LPTSTR)malloc(cchNameString * sizeof(TCHAR));
402 if (!pszNameString)
403 {
404 printf("Memory allocation failed\n");
405 return 0;
406 }
407 cchNameString = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL,
408 pszNameString, cchNameString);
409 _tprintf(_T("Certificate Name: %s\n"), pszNameString);
410 cred.dwVersion = SCHANNEL_CRED_VERSION;
411 cred.cCreds = 1;
412 cred.paCred = &pCertContext;
413 cred.cSupportedAlgs = 0;
414 cred.palgSupportedAlgs = NULL;
415 cred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER;
416 cred.dwFlags = SCH_CRED_NO_SYSTEM_MAPPER;
417 status = table->AcquireCredentialsHandle(NULL, SCHANNEL_NAME, SECPKG_CRED_INBOUND, NULL, &cred,
418 NULL, NULL, &credentials, NULL);
419
420 if (status != SEC_E_OK)
421 {
422 printf("AcquireCredentialsHandle failure: 0x%08" PRIX32 "\n", status);
423 return 0;
424 }
425
426 extraData = FALSE;
427 g_ServerWait = TRUE;
428 if (!(lpTokenIn = (BYTE*)malloc(cbMaxToken)))
429 {
430 printf("Memory allocation failed\n");
431 return 0;
432 }
433 if (!(lpTokenOut = (BYTE*)malloc(cbMaxToken)))
434 {
435 printf("Memory allocation failed\n");
436 free(lpTokenIn);
437 return 0;
438 }
439 fContextReq = ASC_REQ_STREAM | ASC_REQ_SEQUENCE_DETECT | ASC_REQ_REPLAY_DETECT |
440 ASC_REQ_CONFIDENTIALITY | ASC_REQ_EXTENDED_ERROR;
441
442 do
443 {
444 if (!extraData)
445 {
446 if (g_ServerWait)
447 {
448 if (!ReadFile(g_ServerReadPipe, lpTokenIn, cbMaxToken, &NumberOfBytesRead, NULL))
449 {
450 printf("Failed to read from server pipe\n");
451 return NULL;
452 }
453 }
454 else
455 {
456 NumberOfBytesRead = 0;
457 }
458 }
459
460 extraData = FALSE;
461 g_ServerWait = TRUE;
462 SecBuffer_in[0].BufferType = SECBUFFER_TOKEN;
463 SecBuffer_in[0].pvBuffer = lpTokenIn;
464 SecBuffer_in[0].cbBuffer = NumberOfBytesRead;
465 SecBuffer_in[1].BufferType = SECBUFFER_EMPTY;
466 SecBuffer_in[1].pvBuffer = NULL;
467 SecBuffer_in[1].cbBuffer = 0;
468 SecBufferDesc_in.ulVersion = SECBUFFER_VERSION;
469 SecBufferDesc_in.cBuffers = 2;
470 SecBufferDesc_in.pBuffers = SecBuffer_in;
471 SecBuffer_out[0].BufferType = SECBUFFER_TOKEN;
472 SecBuffer_out[0].pvBuffer = lpTokenOut;
473 SecBuffer_out[0].cbBuffer = cbMaxToken;
474 SecBufferDesc_out.ulVersion = SECBUFFER_VERSION;
475 SecBufferDesc_out.cBuffers = 1;
476 SecBufferDesc_out.pBuffers = SecBuffer_out;
477 status = table->AcceptSecurityContext(
478 &credentials, SecIsValidHandle(&context) ? &context : NULL, &SecBufferDesc_in,
479 fContextReq, 0, &context, &SecBufferDesc_out, &fContextAttr, &expiry);
480
481 if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED) &&
482 (status != SEC_E_INCOMPLETE_MESSAGE))
483 {
484 printf("AcceptSecurityContext unexpected status: 0x%08" PRIX32 "\n", status);
485 return NULL;
486 }
487
488 NumberOfBytesWritten = 0;
489
490 if (status == SEC_E_OK)
491 printf("AcceptSecurityContext status: SEC_E_OK\n");
492 else if (status == SEC_I_CONTINUE_NEEDED)
493 printf("AcceptSecurityContext status: SEC_I_CONTINUE_NEEDED\n");
494 else if (status == SEC_E_INCOMPLETE_MESSAGE)
495 printf("AcceptSecurityContext status: SEC_E_INCOMPLETE_MESSAGE\n");
496
497 printf("Server cBuffers: %" PRIu32 " pBuffers[0]: %" PRIu32 " type: %" PRIu32 "\n",
498 SecBufferDesc_out.cBuffers, SecBufferDesc_out.pBuffers[0].cbBuffer,
499 SecBufferDesc_out.pBuffers[0].BufferType);
500 printf("Server Input cBuffers: %" PRIu32 " pBuffers[0]: %" PRIu32 " type: %" PRIu32
501 " pBuffers[1]: %" PRIu32 " type: %" PRIu32 "\n",
502 SecBufferDesc_in.cBuffers, SecBufferDesc_in.pBuffers[0].cbBuffer,
503 SecBufferDesc_in.pBuffers[0].BufferType, SecBufferDesc_in.pBuffers[1].cbBuffer,
504 SecBufferDesc_in.pBuffers[1].BufferType);
505
506 if (SecBufferDesc_in.pBuffers[1].BufferType == SECBUFFER_EXTRA)
507 {
508 printf("AcceptSecurityContext SECBUFFER_EXTRA\n");
509 pSecBuffer = &SecBufferDesc_in.pBuffers[1];
510 CopyMemory(lpTokenIn, &lpTokenIn[NumberOfBytesRead - pSecBuffer->cbBuffer],
511 pSecBuffer->cbBuffer);
512 NumberOfBytesRead = pSecBuffer->cbBuffer;
513 continue;
514 }
515
516 if (status != SEC_E_INCOMPLETE_MESSAGE)
517 {
518 pSecBuffer = &SecBufferDesc_out.pBuffers[0];
519
520 if (pSecBuffer->cbBuffer > 0)
521 {
522 printf("Server > Client (%" PRIu32 ")\n", pSecBuffer->cbBuffer);
523 winpr_HexDump("sspi.test", WLOG_DEBUG, (BYTE*)pSecBuffer->pvBuffer,
524 pSecBuffer->cbBuffer);
525
526 if (!WriteFile(g_ClientWritePipe, pSecBuffer->pvBuffer, pSecBuffer->cbBuffer,
527 &NumberOfBytesWritten, NULL))
528 {
529 printf("failed to write to client pipe\n");
530 return NULL;
531 }
532 }
533 }
534
535 if (status == SEC_E_OK)
536 {
537 printf("Server Handshake Complete\n");
538 break;
539 }
540 } while (1);
541
542 do
543 {
544 if (schannel_recv(table, g_ServerReadPipe, &context) < 0)
545 break;
546 } while (1);
547
548 return 0;
549}
550
551static int dump_test_certificate_files(void)
552{
553 FILE* fp;
554 char* fullpath = NULL;
555 int ret = -1;
556
557 /*
558 * Output Certificate File
559 */
560 fullpath = GetCombinedPath("/tmp", "localhost.crt");
561 if (!fullpath)
562 return -1;
563
564 fp = winpr_fopen(fullpath, "w+");
565 if (fp)
566 {
567 if (fwrite((void*)test_localhost_crt, sizeof(test_localhost_crt), 1, fp) != 1)
568 goto out_fail;
569 fclose(fp);
570 fp = NULL;
571 }
572 free(fullpath);
573
574 /*
575 * Output Private Key File
576 */
577 fullpath = GetCombinedPath("/tmp", "localhost.key");
578 if (!fullpath)
579 return -1;
580 fp = winpr_fopen(fullpath, "w+");
581 if (fp && fwrite((void*)test_localhost_key, sizeof(test_localhost_key), 1, fp) != 1)
582 goto out_fail;
583
584 ret = 1;
585out_fail:
586 free(fullpath);
587 if (fp)
588 fclose(fp);
589 return ret;
590}
591
592int TestSchannel(int argc, char* argv[])
593{
594 int count;
595 ALG_ID algId;
596 HANDLE thread;
597 BYTE* lpTokenIn;
598 BYTE* lpTokenOut;
599 TimeStamp expiry;
600 UINT32 cbMaxToken;
601 SCHANNEL_CRED cred = { 0 };
602 UINT32 fContextReq;
603 ULONG fContextAttr;
604 CtxtHandle context;
605 CredHandle credentials;
606 SECURITY_STATUS status;
607 PSecPkgInfo pPackageInfo;
608 PSecBuffer pSecBuffer;
609 PSecurityFunctionTable table;
610 DWORD NumberOfBytesRead;
611 DWORD NumberOfBytesWritten;
612 SecPkgCred_SupportedAlgs SupportedAlgs = { 0 };
613 SecPkgCred_CipherStrengths CipherStrengths = { 0 };
614 SecPkgCred_SupportedProtocols SupportedProtocols = { 0 };
615 return 0; /* disable by default - causes crash */
616 sspi_GlobalInit();
617 dump_test_certificate_files();
618 SecInvalidateHandle(&context);
619 SecInvalidateHandle(&credentials);
620
621 if (!CreatePipe(&g_ClientReadPipe, &g_ClientWritePipe, NULL, 0))
622 {
623 printf("Failed to create client pipe\n");
624 return -1;
625 }
626
627 if (!CreatePipe(&g_ServerReadPipe, &g_ServerWritePipe, NULL, 0))
628 {
629 printf("Failed to create server pipe\n");
630 return -1;
631 }
632
633 if (!(thread = CreateThread(NULL, 0, schannel_test_server_thread, NULL, 0, NULL)))
634 {
635 printf("Failed to create server thread\n");
636 return -1;
637 }
638
639 table = InitSecurityInterface();
640 status = QuerySecurityPackageInfo(SCHANNEL_NAME, &pPackageInfo);
641
642 if (status != SEC_E_OK)
643 {
644 printf("QuerySecurityPackageInfo failure: 0x%08" PRIX32 "\n", status);
645 return -1;
646 }
647
648 cbMaxToken = pPackageInfo->cbMaxToken;
649 cred.dwVersion = SCHANNEL_CRED_VERSION;
650 cred.cCreds = 0;
651 cred.paCred = NULL;
652 cred.cSupportedAlgs = 0;
653 cred.palgSupportedAlgs = NULL;
654 cred.grbitEnabledProtocols = SP_PROT_SSL3TLS1_CLIENTS;
655 cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS;
656 cred.dwFlags |= SCH_CRED_MANUAL_CRED_VALIDATION;
657 cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
658 status = table->AcquireCredentialsHandle(NULL, SCHANNEL_NAME, SECPKG_CRED_OUTBOUND, NULL, &cred,
659 NULL, NULL, &credentials, NULL);
660
661 if (status != SEC_E_OK)
662 {
663 printf("AcquireCredentialsHandle failure: 0x%08" PRIX32 "\n", status);
664 return -1;
665 }
666
667 status =
668 table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_SUPPORTED_ALGS, &SupportedAlgs);
669
670 if (status != SEC_E_OK)
671 {
672 printf("QueryCredentialsAttributes SECPKG_ATTR_SUPPORTED_ALGS failure: 0x%08" PRIX32 "\n",
673 status);
674 return -1;
675 }
676
682 printf("SupportedAlgs: %" PRIu32 "\n", SupportedAlgs.cSupportedAlgs);
683
684 for (DWORD index = 0; index < SupportedAlgs.cSupportedAlgs; index++)
685 {
686 algId = SupportedAlgs.palgSupportedAlgs[index];
687 printf("\t0x%08" PRIX32 " CLASS: %" PRIu32 " TYPE: %" PRIu32 " SID: %" PRIu32 "\n", algId,
688 ((GET_ALG_CLASS(algId)) >> 13), ((GET_ALG_TYPE(algId)) >> 9), GET_ALG_SID(algId));
689 }
690
691 printf("\n");
692 status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_CIPHER_STRENGTHS,
693 &CipherStrengths);
694
695 if (status != SEC_E_OK)
696 {
697 printf("QueryCredentialsAttributes SECPKG_ATTR_CIPHER_STRENGTHS failure: 0x%08" PRIX32 "\n",
698 status);
699 return -1;
700 }
701
702 /* CipherStrengths: Minimum: 40 Maximum: 256 */
703 printf("CipherStrengths: Minimum: %" PRIu32 " Maximum: %" PRIu32 "\n",
704 CipherStrengths.dwMinimumCipherStrength, CipherStrengths.dwMaximumCipherStrength);
705 status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_SUPPORTED_PROTOCOLS,
706 &SupportedProtocols);
707
708 if (status != SEC_E_OK)
709 {
710 printf("QueryCredentialsAttributes SECPKG_ATTR_SUPPORTED_PROTOCOLS failure: 0x%08" PRIX32
711 "\n",
712 status);
713 return -1;
714 }
715
716 /* SupportedProtocols: 0x208A0 */
717 printf("SupportedProtocols: 0x%08" PRIX32 "\n", SupportedProtocols.grbitProtocol);
718 fContextReq = ISC_REQ_STREAM | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
719 ISC_REQ_CONFIDENTIALITY | ISC_RET_EXTENDED_ERROR |
720 ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_INTEGRITY;
721 if (!(lpTokenIn = (BYTE*)malloc(cbMaxToken)))
722 {
723 printf("Memory allocation failed\n");
724 return -1;
725 }
726 if (!(lpTokenOut = (BYTE*)malloc(cbMaxToken)))
727 {
728 printf("Memory allocation failed\n");
729 return -1;
730 }
731 g_ClientWait = FALSE;
732
733 do
734 {
735 SecBuffer SecBuffer_in[2] = { 0 };
736 SecBuffer SecBuffer_out[1] = { 0 };
737 SecBufferDesc SecBufferDesc_in = { 0 };
738 SecBufferDesc SecBufferDesc_out = { 0 };
739 if (g_ClientWait)
740 {
741 if (!ReadFile(g_ClientReadPipe, lpTokenIn, cbMaxToken, &NumberOfBytesRead, NULL))
742 {
743 printf("failed to read from server pipe\n");
744 return -1;
745 }
746 }
747 else
748 {
749 NumberOfBytesRead = 0;
750 }
751
752 g_ClientWait = TRUE;
753 printf("NumberOfBytesRead: %" PRIu32 "\n", NumberOfBytesRead);
754 SecBuffer_in[0].BufferType = SECBUFFER_TOKEN;
755 SecBuffer_in[0].pvBuffer = lpTokenIn;
756 SecBuffer_in[0].cbBuffer = NumberOfBytesRead;
757 SecBuffer_in[1].pvBuffer = NULL;
758 SecBuffer_in[1].cbBuffer = 0;
759 SecBuffer_in[1].BufferType = SECBUFFER_EMPTY;
760 SecBufferDesc_in.ulVersion = SECBUFFER_VERSION;
761 SecBufferDesc_in.cBuffers = 2;
762 SecBufferDesc_in.pBuffers = SecBuffer_in;
763 SecBuffer_out[0].BufferType = SECBUFFER_TOKEN;
764 SecBuffer_out[0].pvBuffer = lpTokenOut;
765 SecBuffer_out[0].cbBuffer = cbMaxToken;
766 SecBufferDesc_out.ulVersion = SECBUFFER_VERSION;
767 SecBufferDesc_out.cBuffers = 1;
768 SecBufferDesc_out.pBuffers = SecBuffer_out;
769 status = table->InitializeSecurityContext(
770 &credentials, SecIsValidHandle(&context) ? &context : NULL, _T("localhost"),
771 fContextReq, 0, 0, &SecBufferDesc_in, 0, &context, &SecBufferDesc_out, &fContextAttr,
772 &expiry);
773
774 if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED) &&
775 (status != SEC_E_INCOMPLETE_MESSAGE))
776 {
777 printf("InitializeSecurityContext unexpected status: 0x%08" PRIX32 "\n", status);
778 return -1;
779 }
780
781 NumberOfBytesWritten = 0;
782
783 if (status == SEC_E_OK)
784 printf("InitializeSecurityContext status: SEC_E_OK\n");
785 else if (status == SEC_I_CONTINUE_NEEDED)
786 printf("InitializeSecurityContext status: SEC_I_CONTINUE_NEEDED\n");
787 else if (status == SEC_E_INCOMPLETE_MESSAGE)
788 printf("InitializeSecurityContext status: SEC_E_INCOMPLETE_MESSAGE\n");
789
790 printf("Client Output cBuffers: %" PRIu32 " pBuffers[0]: %" PRIu32 " type: %" PRIu32 "\n",
791 SecBufferDesc_out.cBuffers, SecBufferDesc_out.pBuffers[0].cbBuffer,
792 SecBufferDesc_out.pBuffers[0].BufferType);
793 printf("Client Input cBuffers: %" PRIu32 " pBuffers[0]: %" PRIu32 " type: %" PRIu32
794 " pBuffers[1]: %" PRIu32 " type: %" PRIu32 "\n",
795 SecBufferDesc_in.cBuffers, SecBufferDesc_in.pBuffers[0].cbBuffer,
796 SecBufferDesc_in.pBuffers[0].BufferType, SecBufferDesc_in.pBuffers[1].cbBuffer,
797 SecBufferDesc_in.pBuffers[1].BufferType);
798
799 if (status != SEC_E_INCOMPLETE_MESSAGE)
800 {
801 pSecBuffer = &SecBufferDesc_out.pBuffers[0];
802
803 if (pSecBuffer->cbBuffer > 0)
804 {
805 printf("Client > Server (%" PRIu32 ")\n", pSecBuffer->cbBuffer);
806 winpr_HexDump("sspi.test", WLOG_DEBUG, (BYTE*)pSecBuffer->pvBuffer,
807 pSecBuffer->cbBuffer);
808
809 if (!WriteFile(g_ServerWritePipe, pSecBuffer->pvBuffer, pSecBuffer->cbBuffer,
810 &NumberOfBytesWritten, NULL))
811 {
812 printf("failed to write to server pipe\n");
813 return -1;
814 }
815 }
816 }
817
818 if (status == SEC_E_OK)
819 {
820 printf("Client Handshake Complete\n");
821 break;
822 }
823 } while (1);
824
825 count = 0;
826
827 do
828 {
829 if (schannel_send(table, g_ServerWritePipe, &context, test_DummyMessage,
830 sizeof(test_DummyMessage)) < 0)
831 break;
832
833 for (DWORD index = 0; index < sizeof(test_DummyMessage); index++)
834 {
835 BYTE b, ln, hn;
836 b = test_DummyMessage[index];
837 ln = (b & 0x0F);
838 hn = ((b & 0xF0) >> 4);
839 ln = (ln + 1) % 0xF;
840 hn = (ln + 1) % 0xF;
841 b = (ln | (hn << 4));
842 test_DummyMessage[index] = b;
843 }
844
845 Sleep(100);
846 count++;
847 } while (count < 3);
848
849 schannel_send(table, g_ServerWritePipe, &context, test_LastDummyMessage,
850 sizeof(test_LastDummyMessage));
851 (void)WaitForSingleObject(thread, INFINITE);
852 sspi_GlobalFinish();
853 return 0;
854}