2 Unix SMB/CIFS implementation.
4 Validate the krb5 pac generation routines
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "system/kerberos.h"
26 #include "system/time.h"
27 #include "system/network.h"
28 #include "auth/auth.h"
29 #include "auth/kerberos/kerberos.h"
30 #include "librpc/gen_ndr/ndr_krb5pac.h"
31 #include "auth/auth.h"
33 static BOOL torture_pac_self_check(void)
36 TALLOC_CTX *mem_ctx = talloc_named(NULL, 0, "PAC self check");
38 struct PAC_LOGON_INFO *pac_info;
40 /* Generate a nice, arbitary keyblock */
41 uint8_t server_bytes[16];
42 uint8_t krbtgt_bytes[16];
43 krb5_keyblock server_keyblock;
44 krb5_keyblock krbtgt_keyblock;
48 struct smb_krb5_context *smb_krb5_context;
50 struct auth_serversupplied_info *server_info;
52 ret = smb_krb5_init_context(mem_ctx, &smb_krb5_context);
59 generate_random_buffer(server_bytes, 16);
60 generate_random_buffer(krbtgt_bytes, 16);
62 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
64 server_bytes, sizeof(server_bytes),
67 DEBUG(1, ("Server Keyblock encoding failed: %s\n",
68 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
75 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
77 krbtgt_bytes, sizeof(krbtgt_bytes),
80 DEBUG(1, ("KRBTGT Keyblock encoding failed: %s\n",
81 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
84 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
90 /* We need an input, and this one requires no underlying database */
91 nt_status = auth_anonymous_server_info(mem_ctx, &server_info);
93 if (!NT_STATUS_IS_OK(nt_status)) {
94 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
96 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
102 /* OK, go ahead and make a PAC */
103 ret = kerberos_encode_pac(mem_ctx, server_info,
104 smb_krb5_context->krb5_context,
109 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
113 DEBUG(1, ("PAC encoding failed: %s\n",
114 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
117 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
119 talloc_free(mem_ctx);
123 /* Now check that we can read it back */
124 nt_status = kerberos_decode_pac(mem_ctx, &pac_info,
128 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
131 DEBUG(1, ("PAC decoding failed: %s\n",
132 nt_errstr(nt_status)));
134 talloc_free(mem_ctx);
138 talloc_free(mem_ctx);
143 /* This is the PAC generated on my test network, by my test Win2k3 server.
144 -- abartlet 2005-07-04
147 static const char saved_pac[] = {
148 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00,
149 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
150 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
151 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
152 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08, 0x00, 0xcc, 0xcc, 0xcc, 0xcc,
153 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x30, 0xdf, 0xa6, 0xcb,
154 0x4f, 0x7d, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff,
155 0xff, 0xff, 0xff, 0x7f, 0xc0, 0x3c, 0x4e, 0x59, 0x62, 0x73, 0xc5, 0x01, 0xc0, 0x3c, 0x4e, 0x59,
156 0x62, 0x73, 0xc5, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x16, 0x00, 0x16, 0x00,
157 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x65, 0x00, 0x00, 0x00,
160 0xed, 0x03, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x00,
161 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x16, 0x00, 0x20, 0x00, 0x02, 0x00, 0x16, 0x00, 0x18, 0x00,
163 0x24, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
164 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
168 0x57, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00,
169 0x41, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
174 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x57, 0x00, 0x32, 0x00,
175 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x46, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x4c, 0x00,
176 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x57, 0x00, 0x49, 0x00,
177 0x4e, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x54, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4e, 0x00,
178 0x4b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
179 0x15, 0x00, 0x00, 0x00, 0x11, 0x2f, 0xaf, 0xb5, 0x90, 0x04, 0x1b, 0xec, 0x50, 0x3b, 0xec, 0xdc,
180 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
181 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x80, 0x66, 0x28, 0xea, 0x37, 0x80, 0xc5, 0x01, 0x16, 0x00, 0x77, 0x00, 0x32, 0x00, 0x30, 0x00,
183 0x30, 0x00, 0x33, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x24, 0x00,
184 0x76, 0xff, 0xff, 0xff, 0x37, 0xd5, 0xb0, 0xf7, 0x24, 0xf0, 0xd6, 0xd4, 0xec, 0x09, 0x86, 0x5a,
185 0xa0, 0xe8, 0xc3, 0xa9, 0x00, 0x00, 0x00, 0x00, 0x76, 0xff, 0xff, 0xff, 0xb4, 0xd8, 0xb8, 0xfe,
186 0x83, 0xb3, 0x13, 0x3f, 0xfc, 0x5c, 0x41, 0xad, 0xe2, 0x64, 0x83, 0xe0, 0x00, 0x00, 0x00, 0x00
189 /* Check with a known 'well formed' PAC, from my test server */
190 static BOOL torture_pac_saved_check(void)
193 TALLOC_CTX *mem_ctx = talloc_named(NULL, 0, "PAC saved check");
195 struct PAC_LOGON_INFO *pac_info;
196 krb5_keyblock server_keyblock;
197 uint8_t server_bytes[16];
201 struct smb_krb5_context *smb_krb5_context;
203 ret = smb_krb5_init_context(mem_ctx, &smb_krb5_context);
206 talloc_free(mem_ctx);
210 /* The machine trust account in use when the above PAC
211 was generated. It used arcfour-hmac-md5, so this is easy */
212 E_md4hash("iqvwmii8CuEkyY", server_bytes);
214 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
215 ENCTYPE_ARCFOUR_HMAC,
216 server_bytes, sizeof(server_bytes),
219 DEBUG(1, ("Server Keyblock encoding failed: %s\n",
220 smb_get_krb5_error_message(smb_krb5_context->krb5_context,
223 talloc_free(mem_ctx);
227 tmp_blob = data_blob_const(saved_pac, sizeof(saved_pac));
229 /* Decode and verify the signaure on the PAC */
230 nt_status = kerberos_decode_pac(mem_ctx, &pac_info,
234 krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
237 DEBUG(1, ("PAC decoding failed: %s\n",
238 nt_errstr(nt_status)));
240 talloc_free(mem_ctx);
243 talloc_free(mem_ctx);
247 BOOL torture_pac(void)
250 ret &= torture_pac_self_check();
251 ret &= torture_pac_saved_check();