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.crypto.encryption;
21
22
23 import java.security.SecureRandom;
24
25 import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
26 import org.apache.directory.shared.kerberos.components.EncryptedData;
27 import org.apache.directory.shared.kerberos.components.EncryptionKey;
28 import org.apache.directory.shared.kerberos.exceptions.KerberosException;
29
30
31
32
33
34 public abstract class EncryptionEngine
35 {
36 private static final SecureRandom random = new SecureRandom();
37
38
39 protected abstract byte[] getDecryptedData( EncryptionKey key, EncryptedData data, KeyUsage usage )
40 throws KerberosException;
41
42
43 protected abstract EncryptedData getEncryptedData( EncryptionKey key, byte[] plainText, KeyUsage usage );
44
45
46 protected abstract EncryptionType getEncryptionType();
47
48
49 protected abstract int getConfounderLength();
50
51
52 protected abstract int getChecksumLength();
53
54
55 protected abstract byte[] encrypt( byte[] plainText, byte[] key );
56
57
58 protected abstract byte[] decrypt( byte[] cipherText, byte[] key );
59
60
61 protected abstract byte[] calculateIntegrity( byte[] plainText, byte[] key, KeyUsage usage );
62
63
64 protected byte[] deriveRandom( byte[] key, byte[] usage, int n, int k )
65 {
66 byte[] nFoldedUsage = NFold.nFold( n, usage );
67
68 int kBytes = k / 8;
69 byte[] result = new byte[kBytes];
70
71 byte[] fillingKey = encrypt( nFoldedUsage, key );
72
73 int pos = 0;
74
75 for ( int i = 0; i < kBytes; i++ )
76 {
77 if ( pos < fillingKey.length )
78 {
79 result[i] = fillingKey[pos];
80 pos++;
81 }
82 else
83 {
84 fillingKey = encrypt( fillingKey, key );
85 pos = 0;
86 result[i] = fillingKey[pos];
87 pos++;
88 }
89 }
90
91 return result;
92 }
93
94
95
96 protected byte[] getRandomBytes( int size )
97 {
98 byte[] bytes = new byte[size];
99
100
101 random.nextBytes( bytes );
102
103 return bytes;
104 }
105
106
107
108 protected byte[] padString( byte encodedString[] )
109 {
110 int x;
111 if ( encodedString.length < 8 )
112 {
113 x = encodedString.length;
114 }
115 else
116 {
117 x = encodedString.length % 8;
118 }
119
120 if ( x == 0 )
121 {
122 return encodedString;
123 }
124
125 byte paddedByteArray[] = new byte[( 8 - x ) + encodedString.length];
126
127 for ( int y = paddedByteArray.length - 1; y > encodedString.length - 1; y-- )
128 {
129 paddedByteArray[y] = 0;
130 }
131
132 System.arraycopy( encodedString, 0, paddedByteArray, 0, encodedString.length );
133
134 return paddedByteArray;
135 }
136
137
138
139 protected byte[] concatenateBytes( byte[] array1, byte[] array2 )
140 {
141 int l1 = array1.length;
142 int l2 = array2.length;
143 byte concatenatedBytes[] = new byte[l1 + l2];
144
145 System.arraycopy( array1, 0, concatenatedBytes, 0, l1 );
146 System.arraycopy( array2, 0, concatenatedBytes, l1, l2 );
147
148 return concatenatedBytes;
149 }
150
151
152
153 protected byte[] removeLeadingBytes( byte[] array, int confounder, int checksum )
154 {
155 byte lessBytes[] = new byte[array.length - confounder - checksum];
156
157 int j = 0;
158 for ( int i = confounder + checksum; i < array.length; i++ )
159 {
160 lessBytes[j] = array[i];
161 j++;
162 }
163
164 return lessBytes;
165 }
166
167
168 protected byte[] removeTrailingBytes( byte[] array, int confounder, int checksum )
169 {
170 byte lessBytes[] = new byte[array.length - confounder - checksum];
171
172 int j = 0;
173 for ( int i = 0; i < array.length - confounder - checksum; i++ )
174 {
175 lessBytes[j] = array[i];
176 j++;
177 }
178
179 return lessBytes;
180 }
181
182
183 protected int getBit( byte[] data, int pos )
184 {
185 int posByte = pos / 8;
186 int posBit = pos % 8;
187
188 byte valByte = data[posByte];
189
190 return valByte >> ( 8 - ( posBit + 1 ) ) & 0x0001;
191 }
192
193
194 protected void setBit( byte[] data, int pos, int val )
195 {
196 int posByte = pos / 8;
197 int posBit = pos % 8;
198 byte oldByte = data[posByte];
199 oldByte = ( byte ) ( ( ( 0xFF7F >> posBit ) & oldByte ) & 0x00FF );
200 byte newByte = ( byte ) ( ( val << ( 8 - ( posBit + 1 ) ) ) | oldByte );
201 data[posByte] = newByte;
202 }
203
204
205
206
207
208
209
210
211
212
213
214
215 protected byte[] getUsageKc( KeyUsage usage )
216 {
217 return getUsage( usage.getOrdinal(), ( byte ) 0x99 );
218 }
219
220
221
222
223
224
225
226
227
228
229
230
231 protected byte[] getUsageKe( KeyUsage usage )
232 {
233 return getUsage( usage.getOrdinal(), ( byte ) 0xAA );
234 }
235
236
237
238
239
240
241
242
243
244
245
246
247 protected byte[] getUsageKi( KeyUsage usage )
248 {
249 return getUsage( usage.getOrdinal(), ( byte ) 0x55 );
250 }
251
252
253 private byte[] getUsage( int usage, byte constant )
254 {
255 byte[] bytes = new byte[5];
256 bytes[0] = ( byte ) ( ( usage >>> 24 ) & 0x000000FF );
257 bytes[1] = ( byte ) ( ( usage >> 16 ) & 0x000000FF );
258 bytes[2] = ( byte ) ( ( usage >> 8 ) & 0x000000FF );
259 bytes[3] = ( byte ) ( usage & 0x00FF );
260 bytes[4] = constant;
261
262 return bytes;
263 }
264 }