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.server.kerberos.shared.exceptions.KerberosException;
26 import org.apache.directory.server.kerberos.shared.messages.value.EncryptedData;
27 import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
28
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 byte concatenatedBytes[] = new byte[array1.length + array2.length];
142
143 for ( int i = 0; i < array1.length; i++ )
144 {
145 concatenatedBytes[i] = array1[i];
146 }
147
148 for ( int j = array1.length; j < concatenatedBytes.length; j++ )
149 {
150 concatenatedBytes[j] = array2[j - array1.length];
151 }
152
153 return concatenatedBytes;
154 }
155
156
157
158 protected byte[] removeLeadingBytes( byte[] array, int confounder, int checksum )
159 {
160 byte lessBytes[] = new byte[array.length - confounder - checksum];
161
162 int j = 0;
163 for ( int i = confounder + checksum; i < array.length; i++ )
164 {
165 lessBytes[j] = array[i];
166 j++;
167 }
168
169 return lessBytes;
170 }
171
172
173 protected byte[] removeTrailingBytes( byte[] array, int confounder, int checksum )
174 {
175 byte lessBytes[] = new byte[array.length - confounder - checksum];
176
177 int j = 0;
178 for ( int i = 0; i < array.length - confounder - checksum; i++ )
179 {
180 lessBytes[j] = array[i];
181 j++;
182 }
183
184 return lessBytes;
185 }
186
187
188 protected int getBit( byte[] data, int pos )
189 {
190 int posByte = pos / 8;
191 int posBit = pos % 8;
192
193 byte valByte = data[posByte];
194 int valInt = valByte >> ( 8 - ( posBit + 1 ) ) & 0x0001;
195 return valInt;
196 }
197
198
199 protected void setBit( byte[] data, int pos, int val )
200 {
201 int posByte = pos / 8;
202 int posBit = pos % 8;
203 byte oldByte = data[posByte];
204 oldByte = ( byte ) ( ( ( 0xFF7F >> posBit ) & oldByte ) & 0x00FF );
205 byte newByte = ( byte ) ( ( val << ( 8 - ( posBit + 1 ) ) ) | oldByte );
206 data[posByte] = newByte;
207 }
208
209
210
211
212
213
214
215
216
217 protected byte[] getUsageKc( KeyUsage usage )
218 {
219 return getUsage( usage.getOrdinal(), ( byte ) 0x99 );
220 }
221
222
223
224
225
226
227
228
229
230 protected byte[] getUsageKe( KeyUsage usage )
231 {
232 return getUsage( usage.getOrdinal(), ( byte ) 0xAA );
233 }
234
235
236
237
238
239
240
241
242
243 protected byte[] getUsageKi( KeyUsage usage )
244 {
245 return getUsage( usage.getOrdinal(), ( byte ) 0x55 );
246 }
247
248
249 private byte[] getUsage( int usage, byte constant )
250 {
251 byte[] bytes = new byte[5];
252 bytes[0] = ( byte ) ( ( usage >>> 24 ) & 0x000000FF );
253 bytes[1] = ( byte ) ( ( usage >> 16 ) & 0x000000FF );
254 bytes[2] = ( byte ) ( ( usage >> 8 ) & 0x000000FF );
255 bytes[3] = ( byte ) ( usage & 0x00FF );
256 bytes[4] = constant;
257
258 return bytes;
259 }
260 }