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 java.util.HashSet;
24 import java.util.Map;
25 import java.util.Set;
26
27 import javax.security.auth.kerberos.KerberosPrincipal;
28
29 import org.apache.directory.server.kerberos.kdc.KdcServer;
30 import org.apache.directory.server.kerberos.shared.KerberosConstants;
31 import org.apache.directory.server.kerberos.shared.KerberosMessageType;
32 import org.apache.directory.server.kerberos.shared.crypto.encryption.CipherTextHandler;
33 import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
34 import org.apache.directory.server.kerberos.shared.crypto.encryption.KerberosKeyFactory;
35 import org.apache.directory.server.kerberos.shared.crypto.encryption.KeyUsage;
36 import org.apache.directory.server.kerberos.shared.io.encoder.EncryptedDataEncoder;
37 import org.apache.directory.server.kerberos.shared.messages.AuthenticationReply;
38 import org.apache.directory.server.kerberos.shared.messages.ErrorMessage;
39 import org.apache.directory.server.kerberos.shared.messages.KdcRequest;
40 import org.apache.directory.server.kerberos.shared.messages.value.EncryptedData;
41 import org.apache.directory.server.kerberos.shared.messages.value.EncryptedTimeStamp;
42 import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
43 import org.apache.directory.server.kerberos.shared.messages.value.KdcOptions;
44 import org.apache.directory.server.kerberos.shared.messages.value.KerberosTime;
45 import org.apache.directory.server.kerberos.shared.messages.value.PaData;
46 import org.apache.directory.server.kerberos.shared.messages.value.RequestBodyModifier;
47 import org.apache.directory.server.kerberos.shared.messages.value.types.PaDataType;
48 import org.apache.directory.server.kerberos.shared.store.PrincipalStore;
49
50
51
52
53
54
55
56
57 public class AuthenticationEncryptionTypeTest extends AbstractAuthenticationServiceTest
58 {
59 private KdcServer config;
60 private PrincipalStore store;
61 private KerberosProtocolHandler handler;
62 private DummySession session;
63
64
65
66
67
68 public AuthenticationEncryptionTypeTest()
69 {
70 config = new KdcServer();
71 store = new MapPrincipalStoreImpl();
72 handler = new KerberosProtocolHandler( config, store );
73 session = new DummySession();
74 lockBox = new CipherTextHandler();
75 }
76
77
78
79
80
81
82
83 public void testRequestDesCbcMd5() throws Exception
84 {
85 RequestBodyModifier modifier = new RequestBodyModifier();
86 modifier.setClientName( getPrincipalName( "hnelson" ) );
87 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
88 modifier.setRealm( "EXAMPLE.COM" );
89
90 Set<EncryptionType> encryptionTypes = new HashSet<EncryptionType>();
91 encryptionTypes.add( EncryptionType.DES_CBC_MD5 );
92
93 modifier.setEType( encryptionTypes );
94 modifier.setNonce( random.nextInt() );
95 modifier.setKdcOptions( new KdcOptions() );
96
97 long now = System.currentTimeMillis();
98 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.DAY );
99 modifier.setTill( requestedEndTime );
100
101 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
102 String passPhrase = "secret";
103 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
104
105 KdcRequest message = new KdcRequest( KerberosConstants.KERBEROS_V5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
106
107 handler.messageReceived( session, message );
108
109 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
110
111 assertEquals( "Encryption type", EncryptionType.DES_CBC_MD5, reply.getEncPart().getEType() );
112 }
113
114
115
116
117
118
119
120 public void testRequestAes128() throws Exception
121 {
122 EncryptionType[] configuredEncryptionTypes =
123 { EncryptionType.AES128_CTS_HMAC_SHA1_96 };
124 config.setEncryptionTypes( configuredEncryptionTypes );
125
126 RequestBodyModifier modifier = new RequestBodyModifier();
127 modifier.setClientName( getPrincipalName( "hnelson" ) );
128 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
129 modifier.setRealm( "EXAMPLE.COM" );
130
131 Set<EncryptionType> encryptionTypes = new HashSet<EncryptionType>();
132 encryptionTypes.add( EncryptionType.AES128_CTS_HMAC_SHA1_96 );
133
134 modifier.setEType( encryptionTypes );
135 modifier.setNonce( random.nextInt() );
136 modifier.setKdcOptions( new KdcOptions() );
137
138 long now = System.currentTimeMillis();
139 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.DAY );
140 modifier.setTill( requestedEndTime );
141
142 String principalName = "hnelson@EXAMPLE.COM";
143 String passPhrase = "secret";
144 Set<EncryptionType> preAuthEncryptionTypes = new HashSet<EncryptionType>();
145 preAuthEncryptionTypes.add( EncryptionType.AES128_CTS_HMAC_SHA1_96 );
146
147 Map<EncryptionType, EncryptionKey> keyMap = KerberosKeyFactory.getKerberosKeys( principalName, passPhrase,
148 preAuthEncryptionTypes );
149 EncryptionKey clientKey = keyMap.get( EncryptionType.AES128_CTS_HMAC_SHA1_96 );
150
151 KerberosTime timeStamp = new KerberosTime();
152 PaData[] paData = getPreAuthEncryptedTimeStamp( clientKey, timeStamp );
153
154 KdcRequest message = new KdcRequest( KerberosConstants.KERBEROS_V5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
155
156 handler.messageReceived( session, message );
157
158 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
159
160 assertTrue( "Requested end time", requestedEndTime.equals( reply.getEndTime() ) );
161 assertTrue( "PRE_AUTHENT flag", reply.getTicket().getEncTicketPart().getFlags().isPreAuth() );
162 assertEquals( "Encryption type", EncryptionType.AES128_CTS_HMAC_SHA1_96, reply.getEncPart().getEType() );
163 }
164
165
166
167
168
169
170
171 public void testNonce() throws Exception
172 {
173 EncryptionType[] configuredEncryptionTypes =
174 { EncryptionType.AES128_CTS_HMAC_SHA1_96 };
175 config.setEncryptionTypes( configuredEncryptionTypes );
176
177 RequestBodyModifier modifier = new RequestBodyModifier();
178 modifier.setClientName( getPrincipalName( "hnelson" ) );
179 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
180 modifier.setRealm( "EXAMPLE.COM" );
181
182 Set<EncryptionType> encryptionTypes = new HashSet<EncryptionType>();
183 encryptionTypes.add( EncryptionType.AES128_CTS_HMAC_SHA1_96 );
184
185 modifier.setEType( encryptionTypes );
186 int nonce = random.nextInt();
187 modifier.setNonce( nonce );
188 modifier.setKdcOptions( new KdcOptions() );
189
190 long now = System.currentTimeMillis();
191 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.DAY );
192 modifier.setTill( requestedEndTime );
193
194 String principalName = "hnelson@EXAMPLE.COM";
195 String passPhrase = "secret";
196 Set<EncryptionType> preAuthEncryptionTypes = new HashSet<EncryptionType>();
197 preAuthEncryptionTypes.add( EncryptionType.AES128_CTS_HMAC_SHA1_96 );
198
199 Map<EncryptionType, EncryptionKey> keyMap = KerberosKeyFactory.getKerberosKeys( principalName, passPhrase,
200 preAuthEncryptionTypes );
201 EncryptionKey clientKey = keyMap.get( EncryptionType.AES128_CTS_HMAC_SHA1_96 );
202
203 KerberosTime timeStamp = new KerberosTime();
204 PaData[] paData = getPreAuthEncryptedTimeStamp( clientKey, timeStamp );
205
206 KdcRequest message = new KdcRequest( KerberosConstants.KERBEROS_V5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
207
208 handler.messageReceived( session, message );
209
210 AuthenticationReply reply = ( AuthenticationReply ) session.getMessage();
211
212 assertTrue( "Requested end time", requestedEndTime.equals( reply.getEndTime() ) );
213 assertTrue( "PRE_AUTHENT flag", reply.getTicket().getEncTicketPart().getFlags().isPreAuth() );
214 assertEquals( "Encryption type", EncryptionType.AES128_CTS_HMAC_SHA1_96, reply.getEncPart().getEType() );
215
216 assertEquals( "Nonce", nonce, reply.getNonce() );
217 }
218
219
220
221
222
223
224
225
226 public void testAes128Configuration() throws Exception
227 {
228 RequestBodyModifier modifier = new RequestBodyModifier();
229 modifier.setClientName( getPrincipalName( "hnelson" ) );
230 modifier.setServerName( getPrincipalName( "krbtgt/EXAMPLE.COM@EXAMPLE.COM" ) );
231 modifier.setRealm( "EXAMPLE.COM" );
232
233 Set<EncryptionType> requestedEncryptionTypes = new HashSet<EncryptionType>();
234 requestedEncryptionTypes.add( EncryptionType.AES128_CTS_HMAC_SHA1_96 );
235
236 modifier.setEType( requestedEncryptionTypes );
237 modifier.setNonce( random.nextInt() );
238 modifier.setKdcOptions( new KdcOptions() );
239
240 long now = System.currentTimeMillis();
241 KerberosTime requestedEndTime = new KerberosTime( now + KerberosTime.DAY );
242 modifier.setTill( requestedEndTime );
243
244 KerberosPrincipal clientPrincipal = new KerberosPrincipal( "hnelson@EXAMPLE.COM" );
245 String passPhrase = "secret";
246 PaData[] paData = getPreAuthEncryptedTimeStamp( clientPrincipal, passPhrase );
247
248 KdcRequest message = new KdcRequest( KerberosConstants.KERBEROS_V5, KerberosMessageType.AS_REQ, paData, modifier.getRequestBody() );
249
250 handler.messageReceived( session, message );
251
252 ErrorMessage error = ( ErrorMessage ) session.getMessage();
253 assertEquals( "KDC has no support for encryption type", 14, error.getErrorCode() );
254 }
255
256
257 protected PaData[] getPreAuthEncryptedTimeStamp( EncryptionKey clientKey, KerberosTime timeStamp )
258 throws Exception
259 {
260 PaData[] paData = new PaData[1];
261
262 EncryptedTimeStamp encryptedTimeStamp = new EncryptedTimeStamp( timeStamp, 0 );
263
264 EncryptedData encryptedData = lockBox.seal( clientKey, encryptedTimeStamp, KeyUsage.NUMBER1 );
265
266 byte[] encodedEncryptedData = EncryptedDataEncoder.encode( encryptedData );
267
268 PaData preAuth = new PaData();
269 preAuth.setPaDataType( PaDataType.PA_ENC_TIMESTAMP );
270 preAuth.setPaDataValue( encodedEncryptedData );
271
272 paData[0] = preAuth;
273
274 return paData;
275 }
276 }