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;
21
22
23 import org.apache.directory.server.core.DefaultDirectoryService;
24 import org.apache.directory.server.core.DirectoryService;
25 import org.apache.directory.server.core.entry.ServerEntry;
26 import org.apache.directory.server.core.integ.IntegrationUtils;
27 import org.apache.directory.server.core.integ.Level;
28 import org.apache.directory.server.core.integ.annotations.ApplyLdifs;
29 import org.apache.directory.server.core.integ.annotations.CleanupLevel;
30 import org.apache.directory.server.core.integ.annotations.Factory;
31 import org.apache.directory.server.core.interceptor.Interceptor;
32 import org.apache.directory.server.core.kerberos.KeyDerivationInterceptor;
33 import org.apache.directory.server.core.partition.Partition;
34 import org.apache.directory.server.xdbm.Index;
35 import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex;
36 import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition;
37 import org.apache.directory.server.integ.LdapServerFactory;
38 import static org.apache.directory.server.integ.ServerIntegrationUtils.getWiredContext;
39 import org.apache.directory.server.integ.SiRunner;
40 import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
41 import org.apache.directory.server.kerberos.shared.io.decoder.EncryptionKeyDecoder;
42 import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
43 import org.apache.directory.server.kerberos.shared.store.KerberosAttribute;
44 import org.apache.directory.server.ldap.LdapService;
45 import org.apache.directory.server.ldap.handlers.bind.MechanismHandler;
46 import org.apache.directory.server.ldap.handlers.bind.cramMD5.CramMd5MechanismHandler;
47 import org.apache.directory.server.ldap.handlers.bind.digestMD5.DigestMd5MechanismHandler;
48 import org.apache.directory.server.ldap.handlers.bind.gssapi.GssapiMechanismHandler;
49 import org.apache.directory.server.ldap.handlers.bind.ntlm.NtlmMechanismHandler;
50 import org.apache.directory.server.ldap.handlers.bind.plain.PlainMechanismHandler;
51 import org.apache.directory.server.ldap.handlers.extended.StoredProcedureExtendedOperationHandler;
52 import org.apache.directory.server.protocol.shared.SocketAcceptor;
53 import org.apache.directory.shared.ldap.constants.SupportedSaslMechanisms;
54 import org.apache.mina.util.AvailablePortFinder;
55 import org.junit.Before;
56 import org.junit.Test;
57 import org.junit.runner.RunWith;
58 import static org.junit.Assert.assertTrue;
59 import static org.junit.Assert.assertFalse;
60 import static org.junit.Assert.assertEquals;
61
62 import javax.crypto.spec.DESKeySpec;
63 import javax.naming.Context;
64 import javax.naming.NamingException;
65 import javax.naming.directory.Attribute;
66 import javax.naming.directory.Attributes;
67 import javax.naming.directory.BasicAttribute;
68 import javax.naming.directory.BasicAttributes;
69 import javax.naming.directory.DirContext;
70 import javax.naming.directory.InitialDirContext;
71 import javax.naming.directory.ModificationItem;
72
73 import java.io.IOException;
74 import java.security.InvalidKeyException;
75 import java.util.Arrays;
76 import java.util.HashMap;
77 import java.util.HashSet;
78 import java.util.Hashtable;
79 import java.util.List;
80 import java.util.Map;
81 import java.util.Set;
82
83
84
85
86
87
88
89
90
91
92 @RunWith ( SiRunner.class )
93 @CleanupLevel ( Level.CLASS )
94 @Factory ( KeyDerivationServiceIT.Factory.class )
95 @ApplyLdifs( {
96
97 "dn: dc=example,dc=com\n" +
98 "dc: example\n" +
99 "objectClass: top\n" +
100 "objectClass: domain\n\n"
101 }
102 )
103 public class KeyDerivationServiceIT
104 {
105 private static final String RDN = "uid=hnelson,ou=users,dc=example,dc=com";
106
107
108 public static LdapService ldapService;
109
110
111 public static class Factory implements LdapServerFactory
112 {
113 public LdapService newInstance() throws Exception
114 {
115 DirectoryService service = new DefaultDirectoryService();
116 IntegrationUtils.doDelete( service.getWorkingDirectory() );
117 service.getChangeLog().setEnabled( true );
118 service.setAllowAnonymousAccess( false );
119 service.setShutdownHookEnabled( false );
120
121 Set<Partition> partitions = new HashSet<Partition>();
122 JdbmPartition partition = new JdbmPartition();
123 partition.setId( "example" );
124 partition.setSuffix( "dc=example,dc=com" );
125
126 Set<Index<?,ServerEntry>> indexedAttrs = new HashSet<Index<?,ServerEntry>>();
127 indexedAttrs.add( new JdbmIndex<String,ServerEntry>( "ou" ) );
128 indexedAttrs.add( new JdbmIndex<String,ServerEntry>( "dc" ) );
129 indexedAttrs.add( new JdbmIndex<String,ServerEntry>( "objectClass" ) );
130 partition.setIndexedAttributes( indexedAttrs );
131
132 partitions.add( partition );
133 service.setPartitions( partitions );
134
135 List<Interceptor> list = service.getInterceptors();
136 list.add( new KeyDerivationInterceptor() );
137 service.setInterceptors( list );
138
139
140
141
142
143 LdapService ldapService = new LdapService();
144 ldapService.setDirectoryService( service );
145 ldapService.setSocketAcceptor( new SocketAcceptor( null ) );
146 ldapService.setIpPort( AvailablePortFinder.getNextAvailable( 1024 ) );
147 ldapService.setAllowAnonymousAccess( false );
148 ldapService.addExtendedOperationHandler( new StoredProcedureExtendedOperationHandler() );
149
150
151
152 Map<String, MechanismHandler> mechanismHandlerMap = new HashMap<String,MechanismHandler>();
153 mechanismHandlerMap.put( SupportedSaslMechanisms.PLAIN, new PlainMechanismHandler() );
154
155 CramMd5MechanismHandler cramMd5MechanismHandler = new CramMd5MechanismHandler();
156 mechanismHandlerMap.put( SupportedSaslMechanisms.CRAM_MD5, cramMd5MechanismHandler );
157
158 DigestMd5MechanismHandler digestMd5MechanismHandler = new DigestMd5MechanismHandler();
159 mechanismHandlerMap.put( SupportedSaslMechanisms.DIGEST_MD5, digestMd5MechanismHandler );
160
161 GssapiMechanismHandler gssapiMechanismHandler = new GssapiMechanismHandler();
162 mechanismHandlerMap.put( SupportedSaslMechanisms.GSSAPI, gssapiMechanismHandler );
163
164 NtlmMechanismHandler ntlmMechanismHandler = new NtlmMechanismHandler();
165 mechanismHandlerMap.put( SupportedSaslMechanisms.NTLM, ntlmMechanismHandler );
166 mechanismHandlerMap.put( SupportedSaslMechanisms.GSS_SPNEGO, ntlmMechanismHandler );
167
168 ldapService.setSaslMechanismHandlers( mechanismHandlerMap );
169 ldapService.setSaslHost( "localhost" );
170
171 return ldapService;
172 }
173 }
174
175
176
177
178
179
180 @Before
181 public void setUp() throws Exception
182 {
183 DirContext schemaRoot = ( DirContext ) getWiredContext( ldapService ).lookup( "ou=schema" );
184
185
186
187
188
189
190 Attributes krb5kdcAttrs = schemaRoot.getAttributes( "cn=Krb5kdc" );
191 boolean isKrb5KdcDisabled = false;
192
193 if ( krb5kdcAttrs.get( "m-disabled" ) != null )
194 {
195 isKrb5KdcDisabled = ( ( String ) krb5kdcAttrs.get( "m-disabled" ).get() ).equalsIgnoreCase( "TRUE" );
196 }
197
198
199 if ( isKrb5KdcDisabled )
200 {
201 Attribute disabled = new BasicAttribute( "m-disabled" );
202 ModificationItem[] mods = new ModificationItem[]
203 { new ModificationItem( DirContext.REMOVE_ATTRIBUTE, disabled ) };
204 schemaRoot.modifyAttributes( "cn=Krb5kdc", mods );
205 }
206
207 DirContext ctx = ( DirContext ) getWiredContext( ldapService ).lookup( "dc=example,dc=com" );
208 Attributes attrs = getOrgUnitAttributes( "users" );
209 DirContext users = ctx.createSubcontext( "ou=users", attrs );
210
211 attrs = getPersonAttributes( "Nelson", "Horatio Nelson", "hnelson", "secret", "hnelson@EXAMPLE.COM" );
212 users.createSubcontext( "uid=hnelson", attrs );
213 }
214
215
216
217
218
219
220
221
222 @Test
223 public void testAddDerivedKeys() throws NamingException, IOException
224 {
225 Hashtable<String, String> env = new Hashtable<String, String>();
226 env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
227 env.put( Context.PROVIDER_URL, "ldap://localhost:" + ldapService.getIpPort() );
228
229 env.put( Context.SECURITY_AUTHENTICATION, "simple" );
230 env.put( Context.SECURITY_PRINCIPAL, "uid=hnelson,ou=users,dc=example,dc=com" );
231 env.put( Context.SECURITY_CREDENTIALS, "secret" );
232 env.put( "java.naming.ldap.attributes.binary", "krb5key" );
233
234 DirContext ctx = new InitialDirContext( env );
235
236 String[] attrIDs =
237 { "uid", "userPassword", KerberosAttribute.KRB5_KEY_AT, KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT };
238
239 Attributes attributes = ctx.getAttributes( RDN, attrIDs );
240
241 String uid = null;
242
243 if ( attributes.get( "uid" ) != null )
244 {
245 uid = ( String ) attributes.get( "uid" ).get();
246 }
247
248 assertEquals( uid, "hnelson" );
249
250 byte[] userPassword = null;
251
252 if ( attributes.get( "userPassword" ) != null )
253 {
254 userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
255 }
256
257
258 assertTrue( "Number of keys", attributes.get( "krb5key" ).size() > 3 );
259
260 byte[] testPasswordBytes =
261 { ( byte ) 0x73, ( byte ) 0x65, ( byte ) 0x63, ( byte ) 0x72, ( byte ) 0x65, ( byte ) 0x74 };
262 assertTrue( Arrays.equals( userPassword, testPasswordBytes ) );
263
264 Attribute krb5key = attributes.get( KerberosAttribute.KRB5_KEY_AT );
265 Map<EncryptionType, EncryptionKey> map = reconstituteKeyMap( krb5key );
266 EncryptionKey encryptionKey = map.get( EncryptionType.DES_CBC_MD5 );
267
268 byte[] testKeyBytes =
269 { ( byte ) 0xF4, ( byte ) 0xA7, ( byte ) 0x13, ( byte ) 0x64, ( byte ) 0x8A, ( byte ) 0x61, ( byte ) 0xCE,
270 ( byte ) 0x5B };
271
272 assertTrue( Arrays.equals( encryptionKey.getKeyValue(), testKeyBytes ) );
273 assertEquals( EncryptionType.DES_CBC_MD5, encryptionKey.getKeyType() );
274
275 int keyVersionNumber = -1;
276
277 if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
278 {
279 keyVersionNumber = Integer.valueOf( ( String ) attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
280 }
281
282 assertEquals( "Key version number", 0, keyVersionNumber );
283 }
284
285
286
287
288
289
290
291
292
293 @Test
294 public void testModifyDerivedKeys() throws NamingException, IOException
295 {
296 Hashtable<String, String> env = new Hashtable<String, String>();
297 env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
298 env.put( Context.PROVIDER_URL, "ldap://localhost:" + ldapService.getIpPort() );
299
300 env.put( Context.SECURITY_AUTHENTICATION, "simple" );
301 env.put( Context.SECURITY_PRINCIPAL, "uid=hnelson,ou=users,dc=example,dc=com" );
302 env.put( Context.SECURITY_CREDENTIALS, "secret" );
303 env.put( "java.naming.ldap.attributes.binary", "krb5key" );
304
305 DirContext ctx = new InitialDirContext( env );
306
307 String newPrincipalName = "hnelson@EXAMPLE.COM";
308 String newUserPassword = "secretsecret";
309
310
311 Attributes attributes = new BasicAttributes( true );
312 Attribute attr = new BasicAttribute( "userPassword", newUserPassword );
313 attributes.put( attr );
314 attr = new BasicAttribute( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, newPrincipalName );
315 attributes.put( attr );
316
317 DirContext person = ( DirContext ) ctx.lookup( RDN );
318 person.modifyAttributes( "", DirContext.REPLACE_ATTRIBUTE, attributes );
319
320
321 person = ( DirContext ) ctx.lookup( RDN );
322
323 attributes = person.getAttributes( "" );
324
325 byte[] userPassword = null;
326
327 if ( attributes.get( "userPassword" ) != null )
328 {
329 userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
330 }
331
332
333 assertTrue( "Number of keys", attributes.get( "krb5key" ).size() > 3 );
334
335 byte[] testBytes =
336 { 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74 };
337 assertTrue( Arrays.equals( userPassword, testBytes ) );
338
339 Attribute krb5key = attributes.get( "krb5key" );
340 Map<EncryptionType, EncryptionKey> map = reconstituteKeyMap( krb5key );
341 EncryptionKey encryptionKey = map.get( EncryptionType.DES_CBC_MD5 );
342
343 byte[] testKeyBytes =
344 { ( byte ) 0x16, ( byte ) 0x4A, ( byte ) 0x6D, ( byte ) 0x89, ( byte ) 0x5D, ( byte ) 0x76, ( byte ) 0x0E,
345 ( byte ) 0x23 };
346
347 assertTrue( Arrays.equals( encryptionKey.getKeyValue(), testKeyBytes ) );
348 assertEquals( EncryptionType.DES_CBC_MD5, encryptionKey.getKeyType() );
349
350 int keyVersionNumber = -1;
351
352 if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
353 {
354 keyVersionNumber = Integer.valueOf( ( String ) attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
355 }
356
357 assertEquals( "Key version number", 1, keyVersionNumber );
358
359 newUserPassword = "secretsecretsecret";
360
361
362 attributes = new BasicAttributes( true );
363 attr = new BasicAttribute( "userPassword", newUserPassword );
364 attributes.put( attr );
365 attr = new BasicAttribute( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, newPrincipalName );
366 attributes.put( attr );
367
368 person = ( DirContext ) ctx.lookup( RDN );
369 person.modifyAttributes( "", DirContext.REPLACE_ATTRIBUTE, attributes );
370
371
372 person = ( DirContext ) ctx.lookup( RDN );
373
374 attributes = person.getAttributes( "" );
375
376 if ( attributes.get( "userPassword" ) != null )
377 {
378 userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
379 }
380
381 assertEquals( "password length", 18, userPassword.length );
382
383 if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
384 {
385 keyVersionNumber = Integer.valueOf( ( String ) attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
386 }
387
388 assertEquals( "Key version number", 2, keyVersionNumber );
389
390 newUserPassword = "secretsecretsecretsecret";
391
392
393 attributes = new BasicAttributes( true );
394 attr = new BasicAttribute( "userPassword", newUserPassword );
395 attributes.put( attr );
396 attr = new BasicAttribute( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, newPrincipalName );
397 attributes.put( attr );
398
399 person = ( DirContext ) ctx.lookup( RDN );
400 person.modifyAttributes( "", DirContext.REPLACE_ATTRIBUTE, attributes );
401
402
403 person = ( DirContext ) ctx.lookup( RDN );
404
405 attributes = person.getAttributes( "" );
406
407 if ( attributes.get( "userPassword" ) != null )
408 {
409 userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
410 }
411
412 assertEquals( "password length", 24, userPassword.length );
413
414 if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
415 {
416 keyVersionNumber = Integer.valueOf( ( String ) attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
417 }
418
419 assertEquals( "Key version number", 3, keyVersionNumber );
420 }
421
422
423
424
425
426
427
428
429
430
431 @Test
432 public void testModifyDerivedKeysWithoutPrincipalName() throws NamingException, IOException
433 {
434 Hashtable<String, String> env = new Hashtable<String, String>();
435 env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" );
436 env.put( Context.PROVIDER_URL, "ldap://localhost:" + ldapService.getIpPort() );
437
438 env.put( Context.SECURITY_AUTHENTICATION, "simple" );
439 env.put( Context.SECURITY_PRINCIPAL, "uid=hnelson,ou=users,dc=example,dc=com" );
440 env.put( Context.SECURITY_CREDENTIALS, "secret" );
441 env.put( "java.naming.ldap.attributes.binary", "krb5key" );
442
443 DirContext ctx = new InitialDirContext( env );
444
445 String newUserPassword = "secretsecret";
446
447
448 Attributes attributes = new BasicAttributes( true );
449 Attribute attr = new BasicAttribute( "userPassword", newUserPassword );
450 attributes.put( attr );
451
452 DirContext person = ( DirContext ) ctx.lookup( RDN );
453 person.modifyAttributes( "", DirContext.REPLACE_ATTRIBUTE, attributes );
454
455
456 person = ( DirContext ) ctx.lookup( RDN );
457
458 attributes = person.getAttributes( "" );
459
460 byte[] userPassword = null;
461
462 if ( attributes.get( "userPassword" ) != null )
463 {
464 userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
465 }
466
467
468 assertTrue( "Number of keys", attributes.get( "krb5key" ).size() > 3 );
469
470 byte[] testBytes =
471 { 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74 };
472 assertTrue( Arrays.equals( userPassword, testBytes ) );
473
474 Attribute krb5key = attributes.get( "krb5key" );
475 Map<EncryptionType, EncryptionKey> map = reconstituteKeyMap( krb5key );
476 EncryptionKey encryptionKey = map.get( EncryptionType.DES_CBC_MD5 );
477
478 byte[] testKeyBytes =
479 { ( byte ) 0x16, ( byte ) 0x4A, ( byte ) 0x6D, ( byte ) 0x89, ( byte ) 0x5D, ( byte ) 0x76, ( byte ) 0x0E,
480 ( byte ) 0x23 };
481
482 assertTrue( Arrays.equals( encryptionKey.getKeyValue(), testKeyBytes ) );
483 assertEquals( EncryptionType.DES_CBC_MD5, encryptionKey.getKeyType() );
484
485 int keyVersionNumber = -1;
486
487 if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
488 {
489 keyVersionNumber = Integer.valueOf( ( String ) attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
490 }
491
492 assertEquals( "Key version number", 1, keyVersionNumber );
493
494 newUserPassword = "secretsecretsecret";
495
496
497 attributes = new BasicAttributes( true );
498 attr = new BasicAttribute( "userPassword", newUserPassword );
499 attributes.put( attr );
500
501 person = ( DirContext ) ctx.lookup( RDN );
502 person.modifyAttributes( "", DirContext.REPLACE_ATTRIBUTE, attributes );
503
504
505 person = ( DirContext ) ctx.lookup( RDN );
506
507 attributes = person.getAttributes( "" );
508
509 if ( attributes.get( "userPassword" ) != null )
510 {
511 userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
512 }
513
514 assertEquals( "password length", 18, userPassword.length );
515
516 if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
517 {
518 keyVersionNumber = Integer.valueOf( ( String ) attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
519 }
520
521 assertEquals( "Key version number", 2, keyVersionNumber );
522
523 newUserPassword = "secretsecretsecretsecret";
524
525
526 attributes = new BasicAttributes( true );
527 attr = new BasicAttribute( "userPassword", newUserPassword );
528 attributes.put( attr );
529
530 person = ( DirContext ) ctx.lookup( RDN );
531 person.modifyAttributes( "", DirContext.REPLACE_ATTRIBUTE, attributes );
532
533
534 person = ( DirContext ) ctx.lookup( RDN );
535
536 attributes = person.getAttributes( "" );
537
538 if ( attributes.get( "userPassword" ) != null )
539 {
540 userPassword = ( byte[] ) attributes.get( "userPassword" ).get();
541 }
542
543 assertEquals( "password length", 24, userPassword.length );
544
545 if ( attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ) != null )
546 {
547 keyVersionNumber = Integer.valueOf( ( String ) attributes.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).get() );
548 }
549
550 assertEquals( "Key version number", 3, keyVersionNumber );
551 }
552
553
554
555
556
557
558
559
560
561 @Test
562 public void testAddRandomKeys() throws NamingException, IOException, InvalidKeyException
563 {
564 Hashtable<String, String> env = new Hashtable<String, String>();
565 env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
566 env.put( "java.naming.provider.url", "ldap://localhost:" + ldapService.getIpPort() + "/ou=users,dc=example,dc=com" );
567 env.put( "java.naming.security.principal", "uid=admin,ou=system" );
568 env.put( "java.naming.security.credentials", "secret" );
569 env.put( "java.naming.security.authentication", "simple" );
570 env.put( "java.naming.ldap.attributes.binary", "krb5key" );
571 DirContext ctx = new InitialDirContext( env );
572
573 Attributes attrs = getPersonAttributes( "Quist", "Thomas Quist", "tquist", "randomKey", "tquist@EXAMPLE.COM" );
574 ctx.createSubcontext( "uid=tquist", attrs );
575
576 attrs = getPersonAttributes( "Fryer", "John Fryer", "jfryer", "randomKey", "jfryer@EXAMPLE.COM" );
577 ctx.createSubcontext( "uid=jfryer", attrs );
578
579 String[] attrIDs =
580 { "uid", "userPassword", "krb5Key" };
581
582 Attributes tquistAttrs = ctx.getAttributes( "uid=tquist", attrIDs );
583 Attributes jfryerAttrs = ctx.getAttributes( "uid=jfryer", attrIDs );
584
585 String uid = null;
586 byte[] userPassword = null;
587
588 if ( tquistAttrs.get( "uid" ) != null )
589 {
590 uid = ( String ) tquistAttrs.get( "uid" ).get();
591 }
592
593 assertEquals( "tquist", uid );
594
595 if ( tquistAttrs.get( "userPassword" ) != null )
596 {
597 userPassword = ( byte[] ) tquistAttrs.get( "userPassword" ).get();
598 }
599
600
601 byte[] testPasswordBytes =
602 { ( byte ) 0x72, ( byte ) 0x61, ( byte ) 0x6E, ( byte ) 0x64, ( byte ) 0x6F, ( byte ) 0x6D, ( byte ) 0x4B,
603 ( byte ) 0x65, ( byte ) 0x79 };
604 assertTrue( Arrays.equals( testPasswordBytes, userPassword ) );
605
606 if ( jfryerAttrs.get( "uid" ) != null )
607 {
608 uid = ( String ) jfryerAttrs.get( "uid" ).get();
609 }
610
611 assertEquals( "jfryer", uid );
612
613 if ( jfryerAttrs.get( "userPassword" ) != null )
614 {
615 userPassword = ( byte[] ) jfryerAttrs.get( "userPassword" ).get();
616 }
617
618 assertTrue( Arrays.equals( testPasswordBytes, userPassword ) );
619
620 byte[] testKeyBytes =
621 { ( byte ) 0xF4, ( byte ) 0xA7, ( byte ) 0x13, ( byte ) 0x64, ( byte ) 0x8A, ( byte ) 0x61, ( byte ) 0xCE,
622 ( byte ) 0x5B };
623
624 Attribute krb5key = tquistAttrs.get( "krb5key" );
625 Map<EncryptionType, EncryptionKey> map = reconstituteKeyMap( krb5key );
626 EncryptionKey encryptionKey = map.get( EncryptionType.DES_CBC_MD5 );
627 byte[] tquistKey = encryptionKey.getKeyValue();
628
629 assertEquals( EncryptionType.DES_CBC_MD5, encryptionKey.getKeyType() );
630
631 krb5key = jfryerAttrs.get( "krb5key" );
632 map = reconstituteKeyMap( krb5key );
633 encryptionKey = map.get( EncryptionType.DES_CBC_MD5 );
634 byte[] jfryerKey = encryptionKey.getKeyValue();
635
636 assertEquals( EncryptionType.DES_CBC_MD5, encryptionKey.getKeyType() );
637
638 assertEquals( "Key length", 8, tquistKey.length );
639 assertEquals( "Key length", 8, jfryerKey.length );
640
641 assertFalse( Arrays.equals( testKeyBytes, tquistKey ) );
642 assertFalse( Arrays.equals( testKeyBytes, jfryerKey ) );
643 assertFalse( Arrays.equals( jfryerKey, tquistKey ) );
644
645 byte[] tquistDerivedKey =
646 { ( byte ) 0xFD, ( byte ) 0x7F, ( byte ) 0x6B, ( byte ) 0x83, ( byte ) 0xA4, ( byte ) 0x76, ( byte ) 0xC1,
647 ( byte ) 0xEA };
648 byte[] jfryerDerivedKey =
649 { ( byte ) 0xA4, ( byte ) 0x10, ( byte ) 0x3B, ( byte ) 0x49, ( byte ) 0xCE, ( byte ) 0x0B, ( byte ) 0xB5,
650 ( byte ) 0x07 };
651
652 assertFalse( Arrays.equals( tquistDerivedKey, tquistKey ) );
653 assertFalse( Arrays.equals( jfryerDerivedKey, jfryerKey ) );
654
655 assertTrue( DESKeySpec.isParityAdjusted( tquistKey, 0 ) );
656 assertTrue( DESKeySpec.isParityAdjusted( jfryerKey, 0 ) );
657 }
658
659
660
661
662
663
664
665
666
667
668
669
670 protected Attributes getPersonAttributes( String sn, String cn, String uid, String userPassword, String principal )
671 {
672 Attributes attrs = new BasicAttributes( true );
673 Attribute ocls = new BasicAttribute( "objectClass" );
674 ocls.add( "top" );
675 ocls.add( "person" );
676 ocls.add( "inetOrgPerson" );
677 ocls.add( "krb5principal" );
678 ocls.add( "krb5kdcentry" );
679 attrs.put( ocls );
680 attrs.put( "cn", cn );
681 attrs.put( "sn", sn );
682 attrs.put( "uid", uid );
683 attrs.put( "userPassword", userPassword );
684 attrs.put( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, principal );
685 attrs.put( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT, "0" );
686
687 return attrs;
688 }
689
690
691
692
693
694
695
696
697 protected Attributes getOrgUnitAttributes( String ou )
698 {
699 Attributes attrs = new BasicAttributes( true );
700 Attribute ocls = new BasicAttribute( "objectClass" );
701 ocls.add( "top" );
702 ocls.add( "organizationalUnit" );
703 attrs.put( ocls );
704 attrs.put( "ou", ou );
705
706 return attrs;
707 }
708
709
710 private Map<EncryptionType, EncryptionKey> reconstituteKeyMap( Attribute krb5key ) throws NamingException,
711 IOException
712 {
713 Map<EncryptionType, EncryptionKey> map = new HashMap<EncryptionType, EncryptionKey>();
714
715 for ( int ii = 0; ii < krb5key.size(); ii++ )
716 {
717 byte[] encryptionKeyBytes = ( byte[] ) krb5key.get( ii );
718 EncryptionKey encryptionKey = EncryptionKeyDecoder.decode( encryptionKeyBytes );
719 map.put( encryptionKey.getKeyType(), encryptionKey );
720 }
721
722 return map;
723 }
724 }