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>
15 static BOOL g_ClientWait = FALSE;
16 static BOOL g_ServerWait = FALSE;
18 static HANDLE g_ClientReadPipe = NULL;
19 static HANDLE g_ClientWritePipe = NULL;
20 static HANDLE g_ServerReadPipe = NULL;
21 static HANDLE g_ServerWritePipe = NULL;
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
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
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
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
215 static int schannel_send(PSecurityFunctionTable table, HANDLE hPipe,
PCtxtHandle phContext,
216 BYTE* buffer, UINT32 length)
219 UINT32 ioBufferLength;
220 BYTE* pMessageBuffer;
223 SECURITY_STATUS status;
224 DWORD NumberOfBytesWritten;
227 status = table->QueryContextAttributes(phContext, SECPKG_ATTR_STREAM_SIZES, &StreamSizes);
228 ioBufferLength = StreamSizes.cbHeader + StreamSizes.cbMaximumMessage + StreamSizes.cbTrailer;
229 ioBuffer = (BYTE*)calloc(1, ioBufferLength);
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;
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
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);
261 if (status != SEC_E_OK)
264 printf(
"Client > Server (%" PRIu32
")\n", ioBufferLength);
265 winpr_HexDump(
"sspi.test", WLOG_DEBUG, ioBuffer, ioBufferLength);
267 if (!WriteFile(hPipe, ioBuffer, ioBufferLength, &NumberOfBytesWritten, NULL))
269 printf(
"schannel_send: failed to write to pipe\n");
276 static int schannel_recv(PSecurityFunctionTable table, HANDLE hPipe,
PCtxtHandle phContext)
279 UINT32 ioBufferLength;
283 SECURITY_STATUS status;
284 DWORD NumberOfBytesRead;
287 status = table->QueryContextAttributes(phContext, SECPKG_ATTR_STREAM_SIZES, &StreamSizes);
288 ioBufferLength = StreamSizes.cbHeader + StreamSizes.cbMaximumMessage + StreamSizes.cbTrailer;
289 ioBuffer = (BYTE*)calloc(1, ioBufferLength);
293 if (!ReadFile(hPipe, ioBuffer, ioBufferLength, &NumberOfBytesRead, NULL))
295 printf(
"schannel_recv: failed to read from pipe\n");
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
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);
324 if (status != SEC_E_OK)
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);
331 if (memcmp(Message.pBuffers[1].pvBuffer, test_LastDummyMessage,
332 sizeof(test_LastDummyMessage)) == 0)
338 static DWORD WINAPI schannel_test_server_thread(LPVOID arg)
351 LPTSTR pszNameString;
352 HCERTSTORE hCertStore;
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);
370 if (status != SEC_E_OK)
372 printf(
"QuerySecurityPackageInfo failure: 0x%08" PRIX32
"\n", status);
376 cbMaxToken = pPackageInfo->cbMaxToken;
377 hCertStore = CertOpenSystemStore(0, _T(
"MY"));
381 printf(
"Error opening system store\n");
385 #ifdef CERT_FIND_HAS_PRIVATE_KEY
386 pCertContext = CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING, 0,
387 CERT_FIND_HAS_PRIVATE_KEY, NULL, NULL);
390 CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL);
395 printf(
"Error finding certificate in store\n");
400 CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0);
401 pszNameString = (LPTSTR)malloc(cchNameString *
sizeof(TCHAR));
404 printf(
"Memory allocation failed\n");
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;
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);
420 if (status != SEC_E_OK)
422 printf(
"AcquireCredentialsHandle failure: 0x%08" PRIX32
"\n", status);
428 if (!(lpTokenIn = (BYTE*)malloc(cbMaxToken)))
430 printf(
"Memory allocation failed\n");
433 if (!(lpTokenOut = (BYTE*)malloc(cbMaxToken)))
435 printf(
"Memory allocation failed\n");
439 fContextReq = ASC_REQ_STREAM | ASC_REQ_SEQUENCE_DETECT | ASC_REQ_REPLAY_DETECT |
440 ASC_REQ_CONFIDENTIALITY | ASC_REQ_EXTENDED_ERROR;
448 if (!ReadFile(g_ServerReadPipe, lpTokenIn, cbMaxToken, &NumberOfBytesRead, NULL))
450 printf(
"Failed to read from server pipe\n");
456 NumberOfBytesRead = 0;
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);
481 if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED) &&
482 (status != SEC_E_INCOMPLETE_MESSAGE))
484 printf(
"AcceptSecurityContext unexpected status: 0x%08" PRIX32
"\n", status);
488 NumberOfBytesWritten = 0;
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");
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);
506 if (SecBufferDesc_in.pBuffers[1].BufferType == SECBUFFER_EXTRA)
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;
516 if (status != SEC_E_INCOMPLETE_MESSAGE)
518 pSecBuffer = &SecBufferDesc_out.pBuffers[0];
520 if (pSecBuffer->cbBuffer > 0)
522 printf(
"Server > Client (%" PRIu32
")\n", pSecBuffer->cbBuffer);
523 winpr_HexDump(
"sspi.test", WLOG_DEBUG, (BYTE*)pSecBuffer->pvBuffer,
524 pSecBuffer->cbBuffer);
526 if (!WriteFile(g_ClientWritePipe, pSecBuffer->pvBuffer, pSecBuffer->cbBuffer,
527 &NumberOfBytesWritten, NULL))
529 printf(
"failed to write to client pipe\n");
535 if (status == SEC_E_OK)
537 printf(
"Server Handshake Complete\n");
544 if (schannel_recv(table, g_ServerReadPipe, &context) < 0)
551 static int dump_test_certificate_files(
void)
554 char* fullpath = NULL;
560 fullpath = GetCombinedPath(
"/tmp",
"localhost.crt");
564 fp = winpr_fopen(fullpath,
"w+");
567 if (fwrite((
void*)test_localhost_crt,
sizeof(test_localhost_crt), 1, fp) != 1)
577 fullpath = GetCombinedPath(
"/tmp",
"localhost.key");
580 fp = winpr_fopen(fullpath,
"w+");
581 if (fp && fwrite((
void*)test_localhost_key,
sizeof(test_localhost_key), 1, fp) != 1)
592 int TestSchannel(
int argc,
char* argv[])
606 SECURITY_STATUS status;
607 PSecPkgInfo pPackageInfo;
609 PSecurityFunctionTable table;
610 DWORD NumberOfBytesRead;
611 DWORD NumberOfBytesWritten;
617 dump_test_certificate_files();
618 SecInvalidateHandle(&context);
619 SecInvalidateHandle(&credentials);
621 if (!CreatePipe(&g_ClientReadPipe, &g_ClientWritePipe, NULL, 0))
623 printf(
"Failed to create client pipe\n");
627 if (!CreatePipe(&g_ServerReadPipe, &g_ServerWritePipe, NULL, 0))
629 printf(
"Failed to create server pipe\n");
633 if (!(thread = CreateThread(NULL, 0, schannel_test_server_thread, NULL, 0, NULL)))
635 printf(
"Failed to create server thread\n");
639 table = InitSecurityInterface();
640 status = QuerySecurityPackageInfo(SCHANNEL_NAME, &pPackageInfo);
642 if (status != SEC_E_OK)
644 printf(
"QuerySecurityPackageInfo failure: 0x%08" PRIX32
"\n", status);
648 cbMaxToken = pPackageInfo->cbMaxToken;
649 cred.dwVersion = SCHANNEL_CRED_VERSION;
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);
661 if (status != SEC_E_OK)
663 printf(
"AcquireCredentialsHandle failure: 0x%08" PRIX32
"\n", status);
668 table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_SUPPORTED_ALGS, &SupportedAlgs);
670 if (status != SEC_E_OK)
672 printf(
"QueryCredentialsAttributes SECPKG_ATTR_SUPPORTED_ALGS failure: 0x%08" PRIX32
"\n",
682 printf(
"SupportedAlgs: %" PRIu32
"\n", SupportedAlgs.cSupportedAlgs);
684 for (DWORD index = 0; index < SupportedAlgs.cSupportedAlgs; index++)
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));
692 status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_CIPHER_STRENGTHS,
695 if (status != SEC_E_OK)
697 printf(
"QueryCredentialsAttributes SECPKG_ATTR_CIPHER_STRENGTHS failure: 0x%08" PRIX32
"\n",
703 printf(
"CipherStrengths: Minimum: %" PRIu32
" Maximum: %" PRIu32
"\n",
704 CipherStrengths.dwMinimumCipherStrength, CipherStrengths.dwMaximumCipherStrength);
705 status = table->QueryCredentialsAttributes(&credentials, SECPKG_ATTR_SUPPORTED_PROTOCOLS,
706 &SupportedProtocols);
708 if (status != SEC_E_OK)
710 printf(
"QueryCredentialsAttributes SECPKG_ATTR_SUPPORTED_PROTOCOLS failure: 0x%08" PRIX32
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)))
723 printf(
"Memory allocation failed\n");
726 if (!(lpTokenOut = (BYTE*)malloc(cbMaxToken)))
728 printf(
"Memory allocation failed\n");
731 g_ClientWait = FALSE;
741 if (!ReadFile(g_ClientReadPipe, lpTokenIn, cbMaxToken, &NumberOfBytesRead, NULL))
743 printf(
"failed to read from server pipe\n");
749 NumberOfBytesRead = 0;
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,
774 if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED) &&
775 (status != SEC_E_INCOMPLETE_MESSAGE))
777 printf(
"InitializeSecurityContext unexpected status: 0x%08" PRIX32
"\n", status);
781 NumberOfBytesWritten = 0;
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");
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);
799 if (status != SEC_E_INCOMPLETE_MESSAGE)
801 pSecBuffer = &SecBufferDesc_out.pBuffers[0];
803 if (pSecBuffer->cbBuffer > 0)
805 printf(
"Client > Server (%" PRIu32
")\n", pSecBuffer->cbBuffer);
806 winpr_HexDump(
"sspi.test", WLOG_DEBUG, (BYTE*)pSecBuffer->pvBuffer,
807 pSecBuffer->cbBuffer);
809 if (!WriteFile(g_ServerWritePipe, pSecBuffer->pvBuffer, pSecBuffer->cbBuffer,
810 &NumberOfBytesWritten, NULL))
812 printf(
"failed to write to server pipe\n");
818 if (status == SEC_E_OK)
820 printf(
"Client Handshake Complete\n");
829 if (schannel_send(table, g_ServerWritePipe, &context, test_DummyMessage,
830 sizeof(test_DummyMessage)) < 0)
833 for (DWORD index = 0; index <
sizeof(test_DummyMessage); index++)
836 b = test_DummyMessage[index];
838 hn = ((b & 0xF0) >> 4);
841 b = (ln | (hn << 4));
842 test_DummyMessage[index] = b;
849 schannel_send(table, g_ServerWritePipe, &context, test_LastDummyMessage,
850 sizeof(test_LastDummyMessage));
851 (void)WaitForSingleObject(thread, INFINITE);