1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.server.kerberos.protocol;
21
22
23 import javax.security.auth.kerberos.KerberosPrincipal;
24
25 import org.apache.directory.server.kerberos.kdc.KdcServer;
26 import org.apache.directory.server.kerberos.shared.KerberosMessageType;
27 import org.apache.directory.server.kerberos.shared.crypto.encryption.CipherTextHandler;
28 import org.apache.directory.server.kerberos.shared.crypto.encryption.KeyUsage;
29 import org.apache.directory.server.kerberos.shared.io.encoder.EncryptedDataEncoder;
30 import org.apache.directory.server.kerberos.shared.messages.ErrorMessage;
31 import org.apache.directory.server.kerberos.shared.messages.KdcRequest;
32 import org.apache.directory.server.kerberos.shared.messages.value.EncryptedData;
33 import org.apache.directory.server.kerberos.shared.messages.value.EncryptedTimeStamp;
34 import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
35 import org.apache.directory.server.kerberos.shared.messages.value.KdcOptions;
36 import org.apache.directory.server.kerberos.shared.messages.value.KerberosTime;
37 import org.apache.directory.server.kerberos.shared.messages.value.PaData;
38 import org.apache.directory.server.kerberos.shared.messages.value.RequestBodyModifier;
39 import org.apache.directory.server.kerberos.shared.messages.value.types.PaDataType;
40 import org.apache.directory.server.kerberos.shared.store.PrincipalStore;
41
42
43
44
45
46
47
48
49
50 public class PreAuthenticationTest extends AbstractAuthenticationServiceTest
51 {
52 private KdcServer config;
53 private PrincipalStore store;
54 private KerberosProtocolHandler handler;
55 private DummySession session;
56
57
58
59
60
61 public PreAuthenticationTest()
62 {
63 config = new KdcServer();
64 store = new MapPrincipalStoreImpl();
65 handler = new KerberosProtocolHandler( config, store );
66 session = new DummySession();
67 lockBox = new CipherTextHandler();
68 }
69
70
71
72
73
74
75
76
77
78
79
80
81 public void testPreAuthenticationRequired()
82 {
83 RequestBodyModifier modifier = new RequestBodyModifier();
84 modifier.setClientName( getPrincipalName( "hnelson" ) );
85 modifier.setServerName( getPrincipalName( "hnelson" ) );
86 modifier.setRealm( "EXAMPLE.COM" );
87 modifier.setEType( config.getEncryptionTypes() );
88
89 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, null, modifier.getRequestBody() );
90
91 handler.messageReceived( session, message );
92
93 ErrorMessage error = ( ErrorMessage ) session.getMessage();
94 assertEquals( "Additional pre-authentication required", 25, error.getErrorCode() );
95 }
96
97
98
99
100
101
102
103
104
105
106
107
108
109 public void testPreAuthenticationIntegrityFailed() throws Exception
110 {
111 RequestBodyModifier modifier = new RequestBodyModifier();
112 modifier.setClientName( getPrincipalName( "hnelson" ) );
113 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
114 modifier.setRealm( "EXAMPLE.COM" );
115 modifier.setEType( config.getEncryptionTypes() );
116
117 modifier.setKdcOptions( new KdcOptions() );
118
119 long now = System.currentTimeMillis();
120
121 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.DAY );
122 modifier.setTill( requestedEndTime );
123
124 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
125
126 String passPhrase = "badpassword";
127 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
128
129 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
130
131 handler.messageReceived( session, message );
132
133 ErrorMessage error = ( ErrorMessage ) session.getMessage();
134 assertEquals( "Integrity check on decrypted field failed", 31, error.getErrorCode() );
135 }
136
137
138
139
140
141
142
143
144
145 public void testPreAuthenticationFailed() throws Exception
146 {
147 RequestBodyModifier modifier = new RequestBodyModifier();
148 modifier.setClientName( getPrincipalName( "hnelson" ) );
149 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
150 modifier.setRealm( "EXAMPLE.COM" );
151 modifier.setEType( config.getEncryptionTypes() );
152
153 modifier.setKdcOptions( new KdcOptions() );
154
155 long now = System.currentTimeMillis();
156
157 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.DAY );
158 modifier.setTill( requestedEndTime );
159
160 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
161
162 KerberosTime timeStamp = new KerberosTime( 0 );
163 String passPhrase = "secret";
164 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase, timeStamp );
165
166 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
167
168 handler.messageReceived( session, message );
169
170 ErrorMessage error = ( ErrorMessage ) session.getMessage();
171
172 assertEquals( "Pre-authentication information was invalid", 24, error.getErrorCode() );
173 }
174
175
176
177
178
179
180
181
182 public void testPreAuthenticationNoSupport() throws Exception
183 {
184 RequestBodyModifier modifier = new RequestBodyModifier();
185 modifier.setClientName( getPrincipalName( "hnelson" ) );
186 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
187 modifier.setRealm( "EXAMPLE.COM" );
188 modifier.setEType( config.getEncryptionTypes() );
189
190 modifier.setKdcOptions( new KdcOptions() );
191
192 long now = System.currentTimeMillis();
193
194 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.DAY );
195 modifier.setTill( requestedEndTime );
196
197 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
198 String passPhrase = "secret";
199 PaData[] paData = getPreAuthPublicKey( clientPrincipal, passPhrase );
200
201 KdcRequest message = new KdcRequest( 5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
202
203 handler.messageReceived( session, message );
204
205 ErrorMessage error = ( ErrorMessage ) session.getMessage();
206
207 assertEquals( "KDC has no support for padata type", 16, error.getErrorCode() );
208 }
209
210
211
212
213
214
215
216
217
218
219
220
221
222 private PaData[] getPreAuthPublicKey( KerberosPrincipal clientPrincipal, String passPhrase )
223 throws Exception
224 {
225 KerberosTime timeStamp = new KerberosTime();
226
227 return getPreAuthPublicKey( clientPrincipal, passPhrase, timeStamp );
228 }
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243 private PaData[] getPreAuthPublicKey( KerberosPrincipal clientPrincipal, String passPhrase,
244 KerberosTime timeStamp ) throws Exception
245 {
246 PaData[] paData = new PaData[1];
247
248 EncryptedTimeStamp encryptedTimeStamp = new EncryptedTimeStamp( timeStamp, 0 );
249
250 EncryptionKey clientKey = getEncryptionKey( clientPrincipal, passPhrase );
251
252 EncryptedData encryptedData = lockBox.seal( clientKey, encryptedTimeStamp, KeyUsage.NUMBER1 );
253
254 byte[] encodedEncryptedData = EncryptedDataEncoder.encode( encryptedData );
255
256 PaData preAuth = new PaData();
257 preAuth.setPaDataType( PaDataType.PA_PK_AS_REQ );
258 preAuth.setPaDataValue( encodedEncryptedData );
259
260 paData[0] = preAuth;
261
262 return paData;
263 }
264 }