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.messages.value;
21
22
23 import java.nio.BufferOverflowException;
24 import java.nio.ByteBuffer;
25
26 import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
27 import org.apache.directory.shared.asn1.AbstractAsn1Object;
28 import org.apache.directory.shared.asn1.ber.tlv.TLV;
29 import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
30 import org.apache.directory.shared.asn1.ber.tlv.Value;
31 import org.apache.directory.shared.asn1.codec.EncoderException;
32 import org.apache.directory.shared.ldap.util.StringTools;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public class EncryptedData extends AbstractAsn1Object
50 {
51
52 private static final Logger log = LoggerFactory.getLogger( EncryptedData.class );
53
54
55 private static final boolean IS_DEBUG = log.isDebugEnabled();
56
57
58 private EncryptionType eType;
59
60
61 private int kvno;
62
63
64 private boolean hasKvno;
65
66
67 private byte[] cipher;
68
69
70 public static final boolean HAS_KVNO = true;
71
72
73 private transient int eTypeTagLength;
74 private transient int kvnoTagLength;
75 private transient int cipherTagLength;
76 private transient int encryptedDataSeqLength;
77
78
79
80
81
82 public EncryptedData()
83 {
84 hasKvno = !HAS_KVNO;
85 }
86
87
88
89
90
91
92
93
94 public EncryptedData( EncryptionType eType, int kvno, byte[] cipher )
95 {
96 this.eType = eType;
97 this.hasKvno = kvno > 0;
98 this.kvno = kvno;
99 this.cipher = cipher;
100 }
101
102
103
104
105
106
107
108
109 public EncryptedData( EncryptionType eType, byte[] cipher )
110 {
111 this.eType = eType;
112 this.hasKvno = !HAS_KVNO;
113 kvno = -1;
114 this.cipher = cipher;
115 }
116
117
118
119
120
121
122
123 public EncryptionType getEType()
124 {
125 return eType;
126 }
127
128
129
130
131
132
133 public void setEType( EncryptionType eType )
134 {
135 this.eType = eType;
136 }
137
138
139
140
141
142
143 public int getKvno()
144 {
145 return hasKvno ? kvno : -1;
146 }
147
148
149
150
151
152 public void setKvno( int kvno )
153 {
154 this.kvno = kvno;
155 }
156
157
158
159
160
161
162 public boolean hasKvno()
163 {
164 return hasKvno;
165 }
166
167
168
169
170
171
172
173 public byte[] getCipher()
174 {
175 return cipher;
176 }
177
178
179
180
181
182 public void setCipher( byte[] cipher )
183 {
184 this.cipher = cipher;
185 }
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207 public int computeLength()
208 {
209 encryptedDataSeqLength = 0;
210
211
212 int eTypeLength = Value.getNbBytes( eType.getOrdinal() );
213 eTypeTagLength = 1 + TLV.getNbBytes( eTypeLength ) + eTypeLength;
214 encryptedDataSeqLength = 1 + TLV.getNbBytes( eTypeTagLength ) + eTypeTagLength;
215
216
217
218 if ( hasKvno )
219 {
220 int kvnoLength = Value.getNbBytes( kvno );
221 kvnoTagLength = 1 + TLV.getNbBytes( kvnoLength ) + kvnoLength;
222 encryptedDataSeqLength += 1 + TLV.getNbBytes( kvnoTagLength ) + kvnoTagLength;
223 }
224 else
225 {
226 kvnoTagLength = 0;
227 }
228
229
230 if ( ( cipher == null ) || ( cipher.length == 0 ) )
231 {
232 cipherTagLength = 1 + 1;
233 }
234 else
235 {
236 cipherTagLength = 1 + TLV.getNbBytes( cipher.length ) + cipher.length;
237 }
238
239 encryptedDataSeqLength += 1 + TLV.getNbBytes( cipherTagLength ) + cipherTagLength;
240
241
242 return 1 + TLV.getNbBytes( encryptedDataSeqLength ) + encryptedDataSeqLength;
243 }
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
264 {
265 if ( buffer == null )
266 {
267 throw new EncoderException( "Cannot put a PDU in a null buffer !" );
268 }
269
270 try
271 {
272
273 buffer.put( UniversalTag.SEQUENCE_TAG );
274 buffer.put( TLV.getBytes( encryptedDataSeqLength ) );
275
276
277 buffer.put( ( byte ) 0xA0 );
278 buffer.put( TLV.getBytes( eTypeTagLength ) );
279
280 Value.encode( buffer, eType.getOrdinal() );
281
282
283 if ( hasKvno )
284 {
285 buffer.put( ( byte ) 0xA1 );
286 buffer.put( TLV.getBytes( kvnoTagLength ) );
287
288 Value.encode( buffer, kvno );
289 }
290
291
292 buffer.put( ( byte ) 0xA2 );
293 buffer.put( TLV.getBytes( cipherTagLength ) );
294 Value.encode( buffer, cipher );
295 }
296 catch ( BufferOverflowException boe )
297 {
298 log.error(
299 "Cannot encode the EncryptedData object, the PDU size is {} when only {} bytes has been allocated", 1
300 + TLV.getNbBytes( encryptedDataSeqLength ) + encryptedDataSeqLength, buffer.capacity() );
301 throw new EncoderException( "The PDU buffer size is too small !" );
302 }
303
304 if ( IS_DEBUG )
305 {
306 log.debug( "EncryptedData encoding : {}", StringTools.dumpBytes( buffer.array() ) );
307 log.debug( "EncryptedData initial value : {}", toString() );
308 }
309
310 return buffer;
311 }
312
313
314
315
316
317 public String toString()
318 {
319 StringBuilder sb = new StringBuilder();
320
321 sb.append( "EncryptedData : {\n" );
322 sb.append( " etype: " ).append( eType ).append( '\n' );
323
324 if ( hasKvno )
325 {
326 sb.append( " kvno: " ).append( kvno ).append( '\n' );
327 }
328
329 sb.append( " cipher: " ).append( StringTools.dumpBytes( cipher ) ).append( "\n}\n" );
330
331 return sb.toString();
332 }
333 }