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
15 static BOOL g_ClientWait = FALSE;
16 static BOOL g_ServerWait = FALSE;
17
18 static HANDLE g_ClientReadPipe = NULL;
19 static HANDLE g_ClientWritePipe = NULL;
20 static HANDLE g_ServerReadPipe = NULL;
21 static HANDLE g_ServerWritePipe = NULL;
22
23 static 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
91 static 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
201 static 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
208 static 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
schannel_send(PSecurityFunctionTable table,HANDLE hPipe,PCtxtHandle phContext,BYTE * buffer,UINT32 length)215 static 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];
222 SecBufferDesc Message;
223 SECURITY_STATUS status;
224 DWORD NumberOfBytesWritten;
225 SecPkgContext_StreamSizes StreamSizes;
226 ZeroMemory(&StreamSizes, sizeof(SecPkgContext_StreamSizes));
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
schannel_recv(PSecurityFunctionTable table,HANDLE hPipe,PCtxtHandle phContext)276 static int schannel_recv(PSecurityFunctionTable table, HANDLE hPipe, PCtxtHandle phContext)
277 {
278 BYTE* ioBuffer;
279 UINT32 ioBufferLength;
280 // BYTE* pMessageBuffer;
281 SecBuffer Buffers[4];
282 SecBufferDesc Message;
283 SECURITY_STATUS status;
284 DWORD NumberOfBytesRead;
285 SecPkgContext_StreamSizes StreamSizes;
286 ZeroMemory(&StreamSizes, sizeof(SecPkgContext_StreamSizes));
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
schannel_test_server_thread(LPVOID arg)338 static 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;
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];
356 SecBuffer SecBuffer_out[2];
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 ZeroMemory(&cred, sizeof(SCHANNEL_CRED));
411 cred.dwVersion = SCHANNEL_CRED_VERSION;
412 cred.cCreds = 1;
413 cred.paCred = &pCertContext;
414 cred.cSupportedAlgs = 0;
415 cred.palgSupportedAlgs = NULL;
416 cred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER;
417 cred.dwFlags = SCH_CRED_NO_SYSTEM_MAPPER;
418 status = table->AcquireCredentialsHandle(NULL, SCHANNEL_NAME, SECPKG_CRED_INBOUND, NULL, &cred,
419 NULL, NULL, &credentials, NULL);
420
421 if (status != SEC_E_OK)
422 {
423 printf("AcquireCredentialsHandle failure: 0x%08" PRIX32 "\n", status);
424 return 0;
425 }
426
427 extraData = FALSE;
428 g_ServerWait = TRUE;
429 if (!(lpTokenIn = (BYTE*)malloc(cbMaxToken)))
430 {
431 printf("Memory allocation failed\n");
432 return 0;
433 }
434 if (!(lpTokenOut = (BYTE*)malloc(cbMaxToken)))
435 {
436 printf("Memory allocation failed\n");
437 free(lpTokenIn);
438 return 0;
439 }
440 fContextReq = ASC_REQ_STREAM | ASC_REQ_SEQUENCE_DETECT | ASC_REQ_REPLAY_DETECT |
441 ASC_REQ_CONFIDENTIALITY | ASC_REQ_EXTENDED_ERROR;
442
443 do
444 {
445 if (!extraData)
446 {
447 if (g_ServerWait)
448 {
449 if (!ReadFile(g_ServerReadPipe, lpTokenIn, cbMaxToken, &NumberOfBytesRead, NULL))
450 {
451 printf("Failed to read from server pipe\n");
452 return NULL;
453 }
454 }
455 else
456 {
457 NumberOfBytesRead = 0;
458 }
459 }
460
461 extraData = FALSE;
462 g_ServerWait = TRUE;
463 SecBuffer_in[0].BufferType = SECBUFFER_TOKEN;
464 SecBuffer_in[0].pvBuffer = lpTokenIn;
465 SecBuffer_in[0].cbBuffer = NumberOfBytesRead;
466 SecBuffer_in[1].BufferType = SECBUFFER_EMPTY;
467 SecBuffer_in[1].pvBuffer = NULL;
468 SecBuffer_in[1].cbBuffer = 0;
469 SecBufferDesc_in.ulVersion = SECBUFFER_VERSION;
470 SecBufferDesc_in.cBuffers = 2;
471 SecBufferDesc_in.pBuffers = SecBuffer_in;
472 SecBuffer_out[0].BufferType = SECBUFFER_TOKEN;
473 SecBuffer_out[0].pvBuffer = lpTokenOut;
474 SecBuffer_out[0].cbBuffer = cbMaxToken;
475 SecBufferDesc_out.ulVersion = SECBUFFER_VERSION;
476 SecBufferDesc_out.cBuffers = 1;
477 SecBufferDesc_out.pBuffers = SecBuffer_out;
478 status = table->AcceptSecurityContext(
479 &credentials, SecIsValidHandle(&context) ? &context : NULL, &SecBufferDesc_in,
480 fContextReq, 0, &context, &SecBufferDesc_out, &fContextAttr, &expiry);
481
482 if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED) &&
483 (status != SEC_E_INCOMPLETE_MESSAGE))
484 {
485 printf("AcceptSecurityContext unexpected status: 0x%08" PRIX32 "\n", status);
486 return NULL;
487 }
488
489 NumberOfBytesWritten = 0;
490
491 if (status == SEC_E_OK)
492 printf("AcceptSecurityContext status: SEC_E_OK\n");
493 else if (status == SEC_I_CONTINUE_NEEDED)
494 printf("AcceptSecurityContext status: SEC_I_CONTINUE_NEEDED\n");
495 else if (status == SEC_E_INCOMPLETE_MESSAGE)
496 printf("AcceptSecurityContext status: SEC_E_INCOMPLETE_MESSAGE\n");
497
498 printf("Server cBuffers: %" PRIu32 " pBuffers[0]: %" PRIu32 " type: %" PRIu32 "\n",
499 SecBufferDesc_out.cBuffers, SecBufferDesc_out.pBuffers[0].cbBuffer,
500 SecBufferDesc_out.pBuffers[0].BufferType);
501 printf("Server Input cBuffers: %" PRIu32 " pBuffers[0]: %" PRIu32 " type: %" PRIu32
502 " pBuffers[1]: %" PRIu32 " type: %" PRIu32 "\n",
503 SecBufferDesc_in.cBuffers, SecBufferDesc_in.pBuffers[0].cbBuffer,
504 SecBufferDesc_in.pBuffers[0].BufferType, SecBufferDesc_in.pBuffers[1].cbBuffer,
505 SecBufferDesc_in.pBuffers[1].BufferType);
506
507 if (SecBufferDesc_in.pBuffers[1].BufferType == SECBUFFER_EXTRA)
508 {
509 printf("AcceptSecurityContext SECBUFFER_EXTRA\n");
510 pSecBuffer = &SecBufferDesc_in.pBuffers[1];
511 CopyMemory(lpTokenIn, &lpTokenIn[NumberOfBytesRead - pSecBuffer->cbBuffer],
512 pSecBuffer->cbBuffer);
513 NumberOfBytesRead = pSecBuffer->cbBuffer;
514 continue;
515 }
516
517 if (status != SEC_E_INCOMPLETE_MESSAGE)
518 {
519 pSecBuffer = &SecBufferDesc_out.pBuffers[0];
520
521 if (pSecBuffer->cbBuffer > 0)
522 {
523 printf("Server > Client (%" PRIu32 ")\n", pSecBuffer->cbBuffer);
524 winpr_HexDump("sspi.test", WLOG_DEBUG, (BYTE*)pSecBuffer->pvBuffer,
525 pSecBuffer->cbBuffer);
526
527 if (!WriteFile(g_ClientWritePipe, pSecBuffer->pvBuffer, pSecBuffer->cbBuffer,
528 &NumberOfBytesWritten, NULL))
529 {
530 printf("failed to write to client pipe\n");
531 return NULL;
532 }
533 }
534 }
535
536 if (status == SEC_E_OK)
537 {
538 printf("Server Handshake Complete\n");
539 break;
540 }
541 } while (1);
542
543 do
544 {
545 if (schannel_recv(table, g_ServerReadPipe, &context) < 0)
546 break;
547 } while (1);
548
549 return 0;
550 }
551
dump_test_certificate_files(void)552 static int dump_test_certificate_files(void)
553 {
554 FILE* fp;
555 char* fullpath = NULL;
556 int ret = -1;
557
558 /*
559 * Output Certificate File
560 */
561 fullpath = GetCombinedPath("/tmp", "localhost.crt");
562 if (!fullpath)
563 return -1;
564
565 fp = winpr_fopen(fullpath, "w+");
566 if (fp)
567 {
568 if (fwrite((void*)test_localhost_crt, sizeof(test_localhost_crt), 1, fp) != 1)
569 goto out_fail;
570 fclose(fp);
571 fp = NULL;
572 }
573 free(fullpath);
574
575 /*
576 * Output Private Key File
577 */
578 fullpath = GetCombinedPath("/tmp", "localhost.key");
579 if (!fullpath)
580 return -1;
581 fp = winpr_fopen(fullpath, "w+");
582 if (fp && fwrite((void*)test_localhost_key, sizeof(test_localhost_key), 1, fp) != 1)
583 goto out_fail;
584
585 ret = 1;
586 out_fail:
587 free(fullpath);
588 if (fp)
589 fclose(fp);
590 return ret;
591 }
592
TestSchannel(int argc,char * argv[])593 int TestSchannel(int argc, char* argv[])
594 {
595 int count;
596 DWORD index;
597 ALG_ID algId;
598 HANDLE thread;
599 BYTE* lpTokenIn;
600 BYTE* lpTokenOut;
601 TimeStamp expiry;
602 UINT32 cbMaxToken;
603 SCHANNEL_CRED cred;
604 UINT32 fContextReq;
605 ULONG fContextAttr;
606 CtxtHandle context;
607 CredHandle credentials;
608 SECURITY_STATUS status;
609 PSecPkgInfo pPackageInfo;
610 PSecBuffer pSecBuffer;
611 SecBuffer SecBuffer_in[2];
612 SecBuffer SecBuffer_out[1];
613 SecBufferDesc SecBufferDesc_in;
614 SecBufferDesc SecBufferDesc_out;
615 PSecurityFunctionTable table;
616 DWORD NumberOfBytesRead;
617 DWORD NumberOfBytesWritten;
618 SecPkgCred_SupportedAlgs SupportedAlgs;
619 SecPkgCred_CipherStrengths CipherStrengths;
620 SecPkgCred_SupportedProtocols SupportedProtocols;
621 return 0; /* disable by default - causes crash */
622 sspi_GlobalInit();
623 dump_test_certificate_files();
624 SecInvalidateHandle(&context);
625 SecInvalidateHandle(&credentials);
626
627 if (!CreatePipe(&g_ClientReadPipe, &g_ClientWritePipe, NULL, 0))
628 {
629 printf("Failed to create client pipe\n");
630 return -1;
631 }
632
633 if (!CreatePipe(&g_ServerReadPipe, &g_ServerWritePipe, NULL, 0))
634 {
635 printf("Failed to create server pipe\n");
636 return -1;
637 }
638
639 if (!(thread = CreateThread(NULL, 0, schannel_test_server_thread, NULL, 0, NULL)))
640 {
641 printf("Failed to create server thread\n");
642 return -1;
643 }
644
645 table = InitSecurityInterface();
646 status = QuerySecurityPackageInfo(SCHANNEL_NAME, &pPackageInfo);
647
648 if (status != SEC_E_OK)
649 {
650 printf("QuerySecurityPackageInfo failure: 0x%08" PRIX32 "\n", status);
651 return -1;
652 }
653
654 cbMaxToken = pPackageInfo->cbMaxToken;
655 ZeroMemory(&cred, sizeof(SCHANNEL_CRED));
656 cred.dwVersion = SCHANNEL_CRED_VERSION;
657 cred.cCreds = 0;
658 cred.paCred = NULL;
659 cred.cSupportedAlgs = 0;
660 cred.palgSupportedAlgs = NULL;
661 cred.grbitEnabledProtocols = SP_PROT_SSL3TLS1_CLIENTS;
662 cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS;
663 cred.dwFlags |= SCH_CRED_MANUAL_CRED_VALIDATION;
664 cred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
665 status = table->AcquireCredentialsHandle(NULL, SCHANNEL_NAME, SECPKG_CRED_OUTBOUND, NULL, &cred,
666 NULL, NULL, &credentials, NULL);
667
668 if (status != SEC_E_OK)
669 {
670 printf("AcquireCredentialsHandle failure: 0x%08" PRIX32 "\n", status);
671 return -1;
672 }
673
674 ZeroMemory(&SupportedAlgs, sizeof(SecPkgCred_SupportedAlgs));
675 status =
676 table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_SUPPORTED_ALGS, &SupportedAlgs);
677
678 if (status != SEC_E_OK)
679 {
680 printf("QueryCredentialsAttributes SECPKG_ATTR_SUPPORTED_ALGS failure: 0x%08" PRIX32 "\n",
681 status);
682 return -1;
683 }
684
685 /**
686 * SupportedAlgs: 15
687 * 0x660E 0x6610 0x6801 0x6603 0x6601 0x8003 0x8004
688 * 0x800C 0x800D 0x800E 0x2400 0xAA02 0xAE06 0x2200 0x2203
689 */
690 printf("SupportedAlgs: %" PRIu32 "\n", SupportedAlgs.cSupportedAlgs);
691
692 for (index = 0; index < SupportedAlgs.cSupportedAlgs; index++)
693 {
694 algId = SupportedAlgs.palgSupportedAlgs[index];
695 printf("\t0x%08" PRIX32 " CLASS: %" PRIu32 " TYPE: %" PRIu32 " SID: %" PRIu32 "\n", algId,
696 ((GET_ALG_CLASS(algId)) >> 13), ((GET_ALG_TYPE(algId)) >> 9), GET_ALG_SID(algId));
697 }
698
699 printf("\n");
700 ZeroMemory(&CipherStrengths, sizeof(SecPkgCred_CipherStrengths));
701 status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_CIPHER_STRENGTHS,
702 &CipherStrengths);
703
704 if (status != SEC_E_OK)
705 {
706 printf("QueryCredentialsAttributes SECPKG_ATTR_CIPHER_STRENGTHS failure: 0x%08" PRIX32 "\n",
707 status);
708 return -1;
709 }
710
711 /* CipherStrengths: Minimum: 40 Maximum: 256 */
712 printf("CipherStrengths: Minimum: %" PRIu32 " Maximum: %" PRIu32 "\n",
713 CipherStrengths.dwMinimumCipherStrength, CipherStrengths.dwMaximumCipherStrength);
714 ZeroMemory(&SupportedProtocols, sizeof(SecPkgCred_SupportedProtocols));
715 status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_SUPPORTED_PROTOCOLS,
716 &SupportedProtocols);
717
718 if (status != SEC_E_OK)
719 {
720 printf("QueryCredentialsAttributes SECPKG_ATTR_SUPPORTED_PROTOCOLS failure: 0x%08" PRIX32
721 "\n",
722 status);
723 return -1;
724 }
725
726 /* SupportedProtocols: 0x208A0 */
727 printf("SupportedProtocols: 0x%08" PRIX32 "\n", SupportedProtocols.grbitProtocol);
728 fContextReq = ISC_REQ_STREAM | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
729 ISC_REQ_CONFIDENTIALITY | ISC_RET_EXTENDED_ERROR |
730 ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_INTEGRITY;
731 if (!(lpTokenIn = (BYTE*)malloc(cbMaxToken)))
732 {
733 printf("Memory allocation failed\n");
734 return -1;
735 }
736 if (!(lpTokenOut = (BYTE*)malloc(cbMaxToken)))
737 {
738 printf("Memory allocation failed\n");
739 return -1;
740 }
741 ZeroMemory(&SecBuffer_in, sizeof(SecBuffer_in));
742 ZeroMemory(&SecBuffer_out, sizeof(SecBuffer_out));
743 ZeroMemory(&SecBufferDesc_in, sizeof(SecBufferDesc));
744 ZeroMemory(&SecBufferDesc_out, sizeof(SecBufferDesc));
745 g_ClientWait = FALSE;
746
747 do
748 {
749 if (g_ClientWait)
750 {
751 if (!ReadFile(g_ClientReadPipe, lpTokenIn, cbMaxToken, &NumberOfBytesRead, NULL))
752 {
753 printf("failed to read from server pipe\n");
754 return -1;
755 }
756 }
757 else
758 {
759 NumberOfBytesRead = 0;
760 }
761
762 g_ClientWait = TRUE;
763 printf("NumberOfBytesRead: %" PRIu32 "\n", NumberOfBytesRead);
764 SecBuffer_in[0].BufferType = SECBUFFER_TOKEN;
765 SecBuffer_in[0].pvBuffer = lpTokenIn;
766 SecBuffer_in[0].cbBuffer = NumberOfBytesRead;
767 SecBuffer_in[1].pvBuffer = NULL;
768 SecBuffer_in[1].cbBuffer = 0;
769 SecBuffer_in[1].BufferType = SECBUFFER_EMPTY;
770 SecBufferDesc_in.ulVersion = SECBUFFER_VERSION;
771 SecBufferDesc_in.cBuffers = 2;
772 SecBufferDesc_in.pBuffers = SecBuffer_in;
773 SecBuffer_out[0].BufferType = SECBUFFER_TOKEN;
774 SecBuffer_out[0].pvBuffer = lpTokenOut;
775 SecBuffer_out[0].cbBuffer = cbMaxToken;
776 SecBufferDesc_out.ulVersion = SECBUFFER_VERSION;
777 SecBufferDesc_out.cBuffers = 1;
778 SecBufferDesc_out.pBuffers = SecBuffer_out;
779 status = table->InitializeSecurityContext(
780 &credentials, SecIsValidHandle(&context) ? &context : NULL, _T("localhost"),
781 fContextReq, 0, 0, &SecBufferDesc_in, 0, &context, &SecBufferDesc_out, &fContextAttr,
782 &expiry);
783
784 if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED) &&
785 (status != SEC_E_INCOMPLETE_MESSAGE))
786 {
787 printf("InitializeSecurityContext unexpected status: 0x%08" PRIX32 "\n", status);
788 return -1;
789 }
790
791 NumberOfBytesWritten = 0;
792
793 if (status == SEC_E_OK)
794 printf("InitializeSecurityContext status: SEC_E_OK\n");
795 else if (status == SEC_I_CONTINUE_NEEDED)
796 printf("InitializeSecurityContext status: SEC_I_CONTINUE_NEEDED\n");
797 else if (status == SEC_E_INCOMPLETE_MESSAGE)
798 printf("InitializeSecurityContext status: SEC_E_INCOMPLETE_MESSAGE\n");
799
800 printf("Client Output cBuffers: %" PRIu32 " pBuffers[0]: %" PRIu32 " type: %" PRIu32 "\n",
801 SecBufferDesc_out.cBuffers, SecBufferDesc_out.pBuffers[0].cbBuffer,
802 SecBufferDesc_out.pBuffers[0].BufferType);
803 printf("Client Input cBuffers: %" PRIu32 " pBuffers[0]: %" PRIu32 " type: %" PRIu32
804 " pBuffers[1]: %" PRIu32 " type: %" PRIu32 "\n",
805 SecBufferDesc_in.cBuffers, SecBufferDesc_in.pBuffers[0].cbBuffer,
806 SecBufferDesc_in.pBuffers[0].BufferType, SecBufferDesc_in.pBuffers[1].cbBuffer,
807 SecBufferDesc_in.pBuffers[1].BufferType);
808
809 if (status != SEC_E_INCOMPLETE_MESSAGE)
810 {
811 pSecBuffer = &SecBufferDesc_out.pBuffers[0];
812
813 if (pSecBuffer->cbBuffer > 0)
814 {
815 printf("Client > Server (%" PRIu32 ")\n", pSecBuffer->cbBuffer);
816 winpr_HexDump("sspi.test", WLOG_DEBUG, (BYTE*)pSecBuffer->pvBuffer,
817 pSecBuffer->cbBuffer);
818
819 if (!WriteFile(g_ServerWritePipe, pSecBuffer->pvBuffer, pSecBuffer->cbBuffer,
820 &NumberOfBytesWritten, NULL))
821 {
822 printf("failed to write to server pipe\n");
823 return -1;
824 }
825 }
826 }
827
828 if (status == SEC_E_OK)
829 {
830 printf("Client Handshake Complete\n");
831 break;
832 }
833 } while (1);
834
835 count = 0;
836
837 do
838 {
839 if (schannel_send(table, g_ServerWritePipe, &context, test_DummyMessage,
840 sizeof(test_DummyMessage)) < 0)
841 break;
842
843 for (index = 0; index < sizeof(test_DummyMessage); index++)
844 {
845 BYTE b, ln, hn;
846 b = test_DummyMessage[index];
847 ln = (b & 0x0F);
848 hn = ((b & 0xF0) >> 4);
849 ln = (ln + 1) % 0xF;
850 hn = (ln + 1) % 0xF;
851 b = (ln | (hn << 4));
852 test_DummyMessage[index] = b;
853 }
854
855 Sleep(100);
856 count++;
857 } while (count < 3);
858
859 schannel_send(table, g_ServerWritePipe, &context, test_LastDummyMessage,
860 sizeof(test_LastDummyMessage));
861 WaitForSingleObject(thread, INFINITE);
862 sspi_GlobalFinish();
863 return 0;
864 }
865