View Javadoc
1   /*
2    *   Licensed to the Apache Software Foundation (ASF) under one
3    *   or more contributor license agreements.  See the NOTICE file
4    *   distributed with this work for additional information
5    *   regarding copyright ownership.  The ASF licenses this file
6    *   to you under the Apache License, Version 2.0 (the
7    *   "License"); you may not use this file except in compliance
8    *   with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing,
13   *   software distributed under the License is distributed on an
14   *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *   KIND, either express or implied.  See the License for the
16   *   specific language governing permissions and limitations
17   *   under the License.
18   *
19   */
20  
21  package org.apache.directory.shared.kerberos.components;
22  
23  
24  import java.nio.BufferOverflowException;
25  import java.nio.ByteBuffer;
26  import java.util.ArrayList;
27  import java.util.List;
28  
29  import org.apache.directory.api.asn1.Asn1Object;
30  import org.apache.directory.api.asn1.EncoderException;
31  import org.apache.directory.api.asn1.ber.tlv.BerValue;
32  import org.apache.directory.api.asn1.ber.tlv.TLV;
33  import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
34  import org.apache.directory.api.util.Strings;
35  import org.apache.directory.server.i18n.I18n;
36  import org.apache.directory.shared.kerberos.KerberosConstants;
37  import org.apache.directory.shared.kerberos.KerberosTime;
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  
41  
42  /**
43   * EncKrbCredPart  ::= [APPLICATION 29] SEQUENCE {
44   *      ticket-info     [0] SEQUENCE OF KrbCredInfo,
45   *      nonce           [1] UInt32 OPTIONAL,
46   *      timestamp       [2] KerberosTime OPTIONAL,
47   *      usec            [3] Microseconds OPTIONAL,
48   *      s-address       [4] HostAddress OPTIONAL,
49   *      r-address       [5] HostAddress OPTIONAL
50   * }
51   *
52   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
53   */
54  public class EncKrbCredPart implements Asn1Object
55  {
56      /** The logger */
57      private static final Logger log = LoggerFactory.getLogger( EncKrbCredPart.class );
58  
59      /** Speedup for logs */
60      private static final boolean IS_DEBUG = log.isDebugEnabled();
61  
62      /** list of KrbCredInfo */
63      private List<KrbCredInfo> ticketInfo;
64  
65      /** the nonce */
66      private Integer nonce;
67  
68      /** the timestamp */
69      private KerberosTime timestamp;
70  
71      /** the microseconds part of the timestamp */
72      private Integer usec;
73  
74      /** the sender's address */
75      private HostAddress senderAddress;
76  
77      /** the recipient's address */
78      private HostAddress recipientAddress;
79  
80      private int ticketInfoSeqLen;
81      private int ticketInfoLen;
82      private int nonceLen;
83      private int timestampLen;
84      private byte[] timestampBytes;
85      private int usecLen;
86      private int senderAddressLen;
87      private int recipientAddressLen;
88      private int encKrbCredPartSeqLen;
89      private int encKrbCredPartLen;
90  
91  
92      /**
93       * computing length of EncKrbCredPart:
94       * 
95       * <pre>
96       *  0x7D L1
97       *   |
98       *   +--&gt; 0x30 L1-2 EncKrbCredPart seq tag
99       *         |
100      *         +--&gt; 0xA0 L2 seq of KrbCredInfo tag
101      *         |     |
102      *         |     +--&gt; 0x30 L2-2 seq tag
103      *         |     |
104      *         |     +--&gt; 0x30 LL1 KrbCredInfo
105      *         |     .      ....
106      *         |     +--&gt; 0x30 LLn KrbCredInfo
107      *         |
108      *         +--&gt; 0xA1 L3 nonce tag
109      *         |     |
110      *         |     +--&gt; 0x02 L3-2 nonce (UInt32)
111      *         |
112      *         +--&gt; 0xA2 11 timestamp tag
113      *         |     |
114      *         |     +--&gt; 0x18 0x0F timestamp (KerberosTime)
115      *         |
116      *         +--&gt; 0xA3 L4 usec tag
117      *         |     |
118      *         |     +--&gt; 0x02 L4-2 usec (Microseconds)
119      *         |
120      *         +--&gt; 0xA4 L5 s-address tag
121      *         |     |
122      *         |     +--&gt; 0x30 L5-2 s-address (HostAddress)
123      *         |
124      *         +--&gt; 0xA5 L6 r-address tag
125      *               |
126      *               +--&gt; 0x30 L6-2 s-address (HostAddress) 
127      *   
128      * </pre> 
129      */
130     @Override
131     public int computeLength()
132     {
133         for ( KrbCredInfo kci : ticketInfo )
134         {
135             ticketInfoSeqLen += kci.computeLength();
136         }
137 
138         ticketInfoLen = 1 + TLV.getNbBytes( ticketInfoSeqLen ) + ticketInfoSeqLen;
139 
140         encKrbCredPartSeqLen = 1 + TLV.getNbBytes( ticketInfoLen ) + ticketInfoLen;
141 
142         if ( nonce != null )
143         {
144             nonceLen = BerValue.getNbBytes( nonce );
145             nonceLen = 1 + TLV.getNbBytes( nonceLen ) + nonceLen;
146             encKrbCredPartSeqLen += 1 + TLV.getNbBytes( nonceLen ) + nonceLen;
147         }
148 
149         if ( timestamp != null )
150         {
151             timestampBytes = timestamp.getBytes();
152             timestampLen = 1 + TLV.getNbBytes( timestampBytes.length ) + timestampBytes.length;
153             encKrbCredPartSeqLen += 1 + TLV.getNbBytes( timestampLen ) + timestampLen;
154         }
155 
156         if ( usec != null )
157         {
158             usecLen = BerValue.getNbBytes( usec );
159             usecLen = 1 + TLV.getNbBytes( usecLen ) + usecLen;
160             encKrbCredPartSeqLen += 1 + TLV.getNbBytes( usecLen ) + usecLen;
161         }
162 
163         if ( senderAddress != null )
164         {
165             senderAddressLen = senderAddress.computeLength();
166             encKrbCredPartSeqLen += 1 + TLV.getNbBytes( senderAddressLen ) + senderAddressLen;
167         }
168 
169         if ( recipientAddress != null )
170         {
171             recipientAddressLen = recipientAddress.computeLength();
172             encKrbCredPartSeqLen += 1 + TLV.getNbBytes( recipientAddressLen ) + recipientAddressLen;
173         }
174 
175         encKrbCredPartLen = 1 + TLV.getNbBytes( encKrbCredPartSeqLen ) + encKrbCredPartSeqLen;
176 
177         return 1 + TLV.getNbBytes( encKrbCredPartLen ) + encKrbCredPartLen;
178     }
179 
180 
181     /**
182      * {@inheritDoc}
183      */
184     @Override
185     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
186     {
187         if ( buffer == null )
188         {
189             throw new EncoderException( I18n.err( I18n.ERR_148 ) );
190         }
191 
192         try
193         {
194             //EncKrbCredPart application tag
195             buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_PART_TAG );
196             buffer.put( TLV.getBytes( encKrbCredPartLen ) );
197 
198             //EncKrbCredPart sequence tag
199             buffer.put( UniversalTag.SEQUENCE.getValue() );
200             buffer.put( TLV.getBytes( encKrbCredPartSeqLen ) );
201 
202             // ticket-info tag
203             buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_TICKET_INFO_TAG );
204             buffer.put( TLV.getBytes( ticketInfoLen ) );
205 
206             // sequence of ticket-info seq tag
207             buffer.put( UniversalTag.SEQUENCE.getValue() );
208             buffer.put( TLV.getBytes( ticketInfoSeqLen ) );
209 
210             for ( KrbCredInfo ki : ticketInfo )
211             {
212                 ki.encode( buffer );
213             }
214 
215             if ( nonce != null )
216             {
217                 // nonce tag and value
218                 buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_PART_NONCE_TAG );
219                 buffer.put( TLV.getBytes( nonceLen ) );
220                 BerValue.encode( buffer, nonce );
221             }
222 
223             if ( timestamp != null )
224             {
225                 // timestamp tag and value
226                 buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_PART_TIMESTAMP_TAG );
227                 buffer.put( TLV.getBytes( timestampLen ) );
228 
229                 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
230                 buffer.put( ( byte ) 0x0F );
231                 buffer.put( timestampBytes );
232             }
233 
234             if ( usec != null )
235             {
236                 // usec tag and value
237                 buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_PART_USEC_TAG );
238                 buffer.put( TLV.getBytes( usecLen ) );
239                 BerValue.encode( buffer, usec );
240             }
241 
242             if ( senderAddress != null )
243             {
244                 // s-address tag and value
245                 buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_PART_SENDER_ADDRESS_TAG );
246                 buffer.put( TLV.getBytes( senderAddressLen ) );
247                 senderAddress.encode( buffer );
248             }
249 
250             if ( recipientAddress != null )
251             {
252                 // r-address tag and value
253                 buffer.put( ( byte ) KerberosConstants.ENC_KRB_CRED_PART_RECIPIENT_ADDRESS_TAG );
254                 buffer.put( TLV.getBytes( recipientAddressLen ) );
255                 recipientAddress.encode( buffer );
256             }
257         }
258         catch ( BufferOverflowException boe )
259         {
260             log.error( I18n.err( I18n.ERR_740_CANNOT_ENCODE_ENC_KRB_CRED_PART, 1 + TLV.getNbBytes( encKrbCredPartLen )
261                 + encKrbCredPartLen, buffer.capacity() ) );
262             throw new EncoderException( I18n.err( I18n.ERR_138 ), boe );
263         }
264 
265         if ( IS_DEBUG )
266         {
267             log.debug( "EncKrbCredPart encoding : {}", Strings.dumpBytes( buffer.array() ) );
268             log.debug( "EncKrbCredPart initial value : {}", this );
269         }
270 
271         return buffer;
272     }
273 
274 
275     /**
276      * @return the ticketInfo
277      */
278     public List<KrbCredInfo> getTicketInfo()
279     {
280         return ticketInfo;
281     }
282 
283 
284     /**
285      * @param ticketInfo the ticketInfo to set
286      */
287     public void setTicketInfo( List<KrbCredInfo> ticketInfo )
288     {
289         this.ticketInfo = ticketInfo;
290     }
291 
292 
293     /**
294      * @return the nonce
295      */
296     public Integer getNonce()
297     {
298         return nonce;
299     }
300 
301 
302     /**
303      * @param nonce the nonce to set
304      */
305     public void setNonce( Integer nonce )
306     {
307         this.nonce = nonce;
308     }
309 
310 
311     /**
312      * @return the timestamp
313      */
314     public KerberosTime getTimestamp()
315     {
316         return timestamp;
317     }
318 
319 
320     /**
321      * @param timestamp the timestamp to set
322      */
323     public void setTimestamp( KerberosTime timestamp )
324     {
325         this.timestamp = timestamp;
326     }
327 
328 
329     /**
330      * @return the usec
331      */
332     public Integer getUsec()
333     {
334         return usec;
335     }
336 
337 
338     /**
339      * @param usec the usec to set
340      */
341     public void setUsec( Integer usec )
342     {
343         this.usec = usec;
344     }
345 
346 
347     /**
348      * @return the senderAddress
349      */
350     public HostAddress getSenderAddress()
351     {
352         return senderAddress;
353     }
354 
355 
356     /**
357      * @param senderAddress the senderAddress to set
358      */
359     public void setSenderAddress( HostAddress senderAddress )
360     {
361         this.senderAddress = senderAddress;
362     }
363 
364 
365     /**
366      * @return the recipientAddress
367      */
368     public HostAddress getRecipientAddress()
369     {
370         return recipientAddress;
371     }
372 
373 
374     /**
375      * @param recipientAddress the recipientAddress to set
376      */
377     public void setRecipientAddress( HostAddress recipientAddress )
378     {
379         this.recipientAddress = recipientAddress;
380     }
381 
382 
383     /**
384      * add KrbCredInfo object to the existing list of ticket-info
385      *
386      * @param info the KrbCredInfo
387      */
388     public void addTicketInfo( KrbCredInfo info )
389     {
390         if ( info == null )
391         {
392             throw new IllegalArgumentException();
393         }
394 
395         if ( ticketInfo == null )
396         {
397             ticketInfo = new ArrayList<>();
398         }
399 
400         ticketInfo.add( info );
401     }
402 
403 
404     /**
405      * @see Object#toString()
406      */
407     public String toString()
408     {
409         StringBuilder sb = new StringBuilder();
410 
411         sb.append( "EncKrbCredPart : {\n" );
412 
413         sb.append( "    ticketInfo: " ).append( ticketInfo ).append( '\n' );
414 
415         if ( nonce != null )
416         {
417             sb.append( "    nonce: " ).append( nonce ).append( '\n' );
418         }
419 
420         if ( timestamp != null )
421         {
422             sb.append( "    timestamp: " ).append( timestamp ).append( '\n' );
423         }
424 
425         if ( usec != null )
426         {
427             sb.append( "    usec: " ).append( usec ).append( '\n' );
428         }
429 
430         if ( senderAddress != null )
431         {
432             sb.append( "    senderAddress: " ).append( senderAddress ).append( '\n' );
433         }
434 
435         if ( recipientAddress != null )
436         {
437             sb.append( "    recipientAddress: " ).append( recipientAddress ).append( '\n' );
438         }
439 
440         sb.append( "}\n" );
441 
442         return sb.toString();
443     }
444 }