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.shared.keytab;
21
22
23 import java.io.UnsupportedEncodingException;
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
28 import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
29 import org.apache.directory.server.kerberos.shared.messages.value.KerberosTime;
30 import org.apache.mina.common.ByteBuffer;
31
32
33
34
35
36
37
38
39 class KeytabDecoder
40 {
41
42
43
44
45 byte[] getKeytabVersion( ByteBuffer buffer )
46 {
47 byte[] version = new byte[2];
48 buffer.get( version );
49
50 return version;
51 }
52
53
54
55
56
57
58
59
60
61 List<KeytabEntry> getKeytabEntries( ByteBuffer buffer )
62 {
63 List<KeytabEntry> entries = new ArrayList<KeytabEntry>();
64
65 while ( buffer.remaining() > 0 )
66 {
67 int size = buffer.getInt();
68 byte[] entry = new byte[size];
69
70 buffer.get( entry );
71 entries.add( getKeytabEntry( ByteBuffer.wrap( entry ) ) );
72 }
73
74 return entries;
75 }
76
77
78
79
80
81
82 private KeytabEntry getKeytabEntry( ByteBuffer buffer )
83 {
84 String principalName = getPrincipalName( buffer );
85
86 long principalType = buffer.getUnsignedInt();
87
88 long time = buffer.getUnsignedInt();
89 KerberosTime timeStamp = new KerberosTime( time * 1000 );
90
91 byte keyVersion = buffer.get();
92
93 EncryptionKey key = getKeyBlock( buffer, keyVersion );
94
95 return new KeytabEntry( principalName, principalType, timeStamp, keyVersion, key );
96 }
97
98
99
100
101
102
103
104
105 private String getPrincipalName( ByteBuffer buffer )
106 {
107 int count = buffer.getUnsignedShort();
108
109
110 String realm = getCountedString( buffer );
111
112 StringBuffer principalNameBuffer = new StringBuffer();
113
114 for ( int ii = 0; ii < count; ii++ )
115 {
116 String nameComponent = getCountedString( buffer );
117
118 principalNameBuffer.append( nameComponent );
119
120 if ( ii < count - 1 )
121 {
122 principalNameBuffer.append( "\\" );
123 }
124 }
125
126 principalNameBuffer.append( "@" + realm );
127
128 return principalNameBuffer.toString();
129 }
130
131
132
133
134
135 private EncryptionKey getKeyBlock( ByteBuffer buffer, int keyVersion )
136 {
137 int type = buffer.getUnsignedShort();
138 byte[] keyblock = getCountedBytes( buffer );
139
140 EncryptionType encryptionType = EncryptionType.getTypeByOrdinal( type );
141 EncryptionKey key = new EncryptionKey( encryptionType, keyblock );
142
143 return key;
144 }
145
146
147
148
149
150
151 private String getCountedString( ByteBuffer buffer )
152 {
153 int length = buffer.getUnsignedShort();
154 byte[] data = new byte[length];
155 buffer.get( data );
156
157 try
158 {
159 return new String( data, "ASCII" );
160 }
161 catch ( UnsupportedEncodingException uee )
162 {
163
164 return "";
165 }
166 }
167
168
169
170
171
172 private byte[] getCountedBytes( ByteBuffer buffer )
173 {
174 int length = buffer.getUnsignedShort();
175 byte[] data = new byte[length];
176 buffer.get( data );
177
178 return data;
179 }
180 }