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  
27  import org.apache.directory.api.asn1.Asn1Object;
28  import org.apache.directory.api.asn1.EncoderException;
29  import org.apache.directory.api.asn1.ber.tlv.BerValue;
30  import org.apache.directory.api.asn1.ber.tlv.TLV;
31  import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
32  import org.apache.directory.api.util.Strings;
33  import org.apache.directory.server.i18n.I18n;
34  import org.apache.directory.shared.kerberos.KerberosConstants;
35  import org.apache.directory.shared.kerberos.KerberosTime;
36  import org.apache.directory.shared.kerberos.flags.TicketFlag;
37  import org.apache.directory.shared.kerberos.flags.TicketFlags;
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  
41  
42  /**
43   * EncTicketPart   ::= [APPLICATION 3] SEQUENCE {
44   *      flags                   [0] TicketFlags,
45   *      key                     [1] EncryptionKey,
46   *      crealm                  [2] Realm,
47   *      cname                   [3] PrincipalName,
48   *      transited               [4] TransitedEncoding,
49   *      authtime                [5] KerberosTime,
50   *      starttime               [6] KerberosTime OPTIONAL,
51   *      endtime                 [7] KerberosTime,
52   *      renew-till              [8] KerberosTime OPTIONAL,
53   *      caddr                   [9] HostAddresses OPTIONAL,
54   *      authorization-data      [10] AuthorizationData OPTIONAL
55   * }
56   *
57   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
58   */
59  public class EncTicketPart implements Asn1Object
60  {
61      /** The logger */
62      private static final Logger log = LoggerFactory.getLogger( EncTicketPart.class );
63  
64      /** Speedup for logs */
65      private static final boolean IS_DEBUG = log.isDebugEnabled();
66  
67      /** the ticket's flags */
68      private TicketFlagsd/kerberos/flags/TicketFlags.html#TicketFlags">TicketFlags flags = new TicketFlags();
69  
70      /** the encryption key */
71      private EncryptionKey key;
72  
73      /** the client's realm */
74      private String cRealm;
75  
76      /** client's principal */
77      private PrincipalName cName;
78  
79      /** field containing list of transited realm names */
80      private TransitedEncoding transited;
81  
82      /** time of initial authentication */
83      private KerberosTime authTime;
84  
85      /** time after which ticket is valid */
86      private KerberosTime startTime;
87  
88      /** ticket's expiry time */
89      private KerberosTime endTime;
90  
91      /** the maximum endtime that may be included in a renewal */
92      private KerberosTime renewtill;
93  
94      /** the addresses from which this ticket can be used */
95      private HostAddresses clientAddresses;
96  
97      /** the authorization data */
98      private AuthorizationData authorizationData;
99  
100     private int flagsLen;
101     private int keyLen;
102     private int cRealmLen;
103     private byte[] cRealmBytes;
104     private int cNameLen;
105     private int transitedLen;
106     private int authTimeLen;
107     private byte[] authTimeBytes;
108     private int startTimeLen;
109     private byte[] startTimeBytes;
110     private int endTimeLen;
111     private byte[] endTimeBytes;
112     private int renewtillLen;
113     private byte[] renewtillBytes;
114     private int clientAddressesLen;
115     private int authzDataLen;
116     private int encTikcetPartSeqLen;
117     private int encTikcetPartLen;
118 
119 
120     /**
121      * compute length for EncTicketPart:
122      * <pre>
123      * 0x63 L1 EncTicketPart tag
124      *  |
125      *  +--&gt; 0x30 L1-2 EncTicketPart seq
126      *        |
127      *        +--&gt; 0xA0 L2 flags tag
128      *        |     |
129      *        |     +--&gt; 0x03 L2-2 flags (BitString)
130      *        |
131      *        +--&gt; 0xA1 L3 key tag
132      *        |     |
133      *        |     +--&gt; 0x30 L3-2 key (EncryptionKey)
134      *        |
135      *        +--&gt; 0xA2 L4 crealm tag
136      *        |     |
137      *        |     +--&gt; 0x1B L4-2 crealm (Realm)
138      *        |
139      *        +--&gt; 0xA3 L5 cname tag
140      *        |     |
141      *        |     +--&gt; 0x30 L5-2 cname (PrincipalName)
142      *        |
143      *        +--&gt; 0xA4 L6 transited tag
144      *        |     |
145      *        |     +--&gt; 0x30 L6-2 transited (TransitedEncoding)
146      *        |
147      *        +--&gt; 0xA5 0x11 authtime tag
148      *        |     |
149      *        |     +--&gt; 0x18 0x0F authtime (KerberosTime)
150      *        |
151      *        +--&gt; [0xA6 0x11 starttime tag
152      *        |     |
153      *        |     +--&gt; 0x18 0x0F starttime (KerberosTime)]
154      *        |
155      *        +--&gt; 0xA7 0x11 endtime tag
156      *        |     |
157      *        |     +--&gt; 0x18 0x0F endtime (KerberosTime)
158      *        |
159      *        +--&gt; [0xA8 0x11 renewtill tag
160      *        |     |
161      *        |     +--&gt; 0x18 0x0F renewtill (KerberosTime)]
162      *        |
163      *        +--&gt; [0xA9 L7 caddr tag
164      *        |     |
165      *        |     +--&gt; 0x30 L7-2 caddre (HostAddresses)]
166      *        |
167      *        +--&gt; [0xAA L8 authorization-data tag
168      *              |
169      *              +--&gt; 0x30 L8-2 authorization-data (AuthorizationData)]
170      * </pre>
171      * 
172      */
173     @Override
174     public int computeLength()
175     {
176         flagsLen = flags.getData().length;
177         flagsLen = 1 + TLV.getNbBytes( flagsLen ) + flagsLen;
178         encTikcetPartSeqLen = 1 + TLV.getNbBytes( flagsLen ) + flagsLen;
179 
180         keyLen = key.computeLength();
181         encTikcetPartSeqLen += 1 + TLV.getNbBytes( keyLen ) + keyLen;
182 
183         cRealmBytes = Strings.getBytesUtf8( cRealm );
184         cRealmLen = 1 + TLV.getNbBytes( cRealmBytes.length ) + cRealmBytes.length;
185         encTikcetPartSeqLen += 1 + TLV.getNbBytes( cRealmLen ) + cRealmLen;
186 
187         cNameLen = cName.computeLength();
188         encTikcetPartSeqLen += 1 + TLV.getNbBytes( cNameLen ) + cNameLen;
189 
190         transitedLen = transited.computeLength();
191         encTikcetPartSeqLen += 1 + TLV.getNbBytes( transitedLen ) + transitedLen;
192 
193         authTimeBytes = authTime.getBytes();
194         authTimeLen = 1 + TLV.getNbBytes( authTimeBytes.length ) + authTimeBytes.length;
195         encTikcetPartSeqLen += 1 + TLV.getNbBytes( authTimeLen ) + authTimeLen;
196 
197         if ( startTime != null )
198         {
199             startTimeBytes = startTime.getBytes();
200             startTimeLen = 1 + TLV.getNbBytes( startTimeBytes.length ) + startTimeBytes.length;
201             encTikcetPartSeqLen += 1 + TLV.getNbBytes( startTimeLen ) + startTimeLen;
202         }
203 
204         endTimeBytes = endTime.getBytes();
205         endTimeLen = 1 + TLV.getNbBytes( endTimeBytes.length ) + endTimeBytes.length;
206         encTikcetPartSeqLen += 1 + TLV.getNbBytes( endTimeLen ) + endTimeLen;
207 
208         if ( renewtill != null )
209         {
210             renewtillBytes = renewtill.getBytes();
211             renewtillLen = 1 + TLV.getNbBytes( renewtillBytes.length ) + renewtillBytes.length;
212             encTikcetPartSeqLen += 1 + TLV.getNbBytes( renewtillLen ) + renewtillLen;
213         }
214 
215         if ( clientAddresses != null )
216         {
217             clientAddressesLen = clientAddresses.computeLength();
218             encTikcetPartSeqLen += 1 + TLV.getNbBytes( clientAddressesLen ) + clientAddressesLen;
219         }
220 
221         if ( authorizationData != null )
222         {
223             authzDataLen = authorizationData.computeLength();
224             encTikcetPartSeqLen += 1 + TLV.getNbBytes( authzDataLen ) + authzDataLen;
225         }
226 
227         encTikcetPartLen = 1 + TLV.getNbBytes( encTikcetPartSeqLen ) + encTikcetPartSeqLen;
228 
229         return 1 + TLV.getNbBytes( encTikcetPartLen ) + encTikcetPartLen;
230     }
231 
232 
233     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
234     {
235         if ( buffer == null )
236         {
237             throw new EncoderException( I18n.err( I18n.ERR_148 ) );
238         }
239 
240         try
241         {
242             // EncTicketPart application tag and length
243             buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_TAG );
244             buffer.put( TLV.getBytes( encTikcetPartLen ) );
245 
246             // EncTicketPart sequence tag and length
247             buffer.put( UniversalTag.SEQUENCE.getValue() );
248             buffer.put( TLV.getBytes( encTikcetPartSeqLen ) );
249 
250             // flags tag and int value
251             buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_FLAGS_TAG );
252             buffer.put( TLV.getBytes( flagsLen ) );
253             BerValue.encode( buffer, flags );
254 
255             // key tag and value
256             buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_KEY_TAG );
257             buffer.put( TLV.getBytes( keyLen ) );
258             key.encode( buffer );
259 
260             // crealm tag and value
261             buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_CREALM_TAG );
262             buffer.put( TLV.getBytes( cRealmLen ) );
263             buffer.put( UniversalTag.GENERAL_STRING.getValue() );
264             buffer.put( TLV.getBytes( cRealmBytes.length ) );
265             buffer.put( cRealmBytes );
266 
267             // cname tag and value
268             buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_CNAME_TAG );
269             buffer.put( TLV.getBytes( cNameLen ) );
270             cName.encode( buffer );
271 
272             // transited tag and value
273             buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_TRANSITED_TAG );
274             buffer.put( TLV.getBytes( transitedLen ) );
275             transited.encode( buffer );
276 
277             // authtime tag and value
278             buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_AUTHTIME_TAG );
279             buffer.put( TLV.getBytes( authTimeLen ) );
280             buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
281             buffer.put( ( byte ) 0x0F );
282             buffer.put( authTimeBytes );
283 
284             if ( startTime != null )
285             {
286                 // strattime tag and value
287                 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_STARTTIME_TAG );
288                 buffer.put( TLV.getBytes( startTimeLen ) );
289                 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
290                 buffer.put( ( byte ) 0x0F );
291                 buffer.put( startTimeBytes );
292             }
293 
294             // endtime tag and value
295             buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_ENDTIME_TAG );
296             buffer.put( TLV.getBytes( endTimeLen ) );
297             buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
298             buffer.put( ( byte ) 0x0F );
299             buffer.put( endTimeBytes );
300 
301             if ( renewtill != null )
302             {
303                 // renewtill tag and value
304                 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_RENEWTILL_TAG );
305                 buffer.put( TLV.getBytes( renewtillLen ) );
306                 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
307                 buffer.put( ( byte ) 0x0F );
308                 buffer.put( renewtillBytes );
309             }
310 
311             if ( clientAddresses != null )
312             {
313                 // caddr tag and value
314                 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_CADDR_TAG );
315                 buffer.put( TLV.getBytes( clientAddressesLen ) );
316                 clientAddresses.encode( buffer );
317             }
318 
319             if ( authorizationData != null )
320             {
321                 // authorization-data tag and value
322                 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_AUTHORIZATION_DATA_TAG );
323                 buffer.put( TLV.getBytes( authzDataLen ) );
324                 authorizationData.encode( buffer );
325             }
326         }
327         catch ( BufferOverflowException boe )
328         {
329             log.error( I18n.err( I18n.ERR_742_CANNOT_ENCODE_ENC_TICKET_PART, 1 + TLV.getNbBytes( encTikcetPartLen )
330                 + encTikcetPartLen, buffer.capacity() ) );
331             throw new EncoderException( I18n.err( I18n.ERR_138 ), boe );
332         }
333 
334         if ( IS_DEBUG )
335         {
336             log.debug( "EncTicketPart encoding : {}", Strings.dumpBytes( buffer.array() ) );
337             log.debug( "EncTicketPart initial value : {}", this );
338         }
339 
340         return buffer;
341     }
342 
343 
344     /**
345      * @return the flags
346      */
347     public TicketFlags getFlags()
348     {
349         return flags;
350     }
351 
352 
353     /**
354      * @param flags the flags to set
355      */
356     public void setFlags( TicketFlags flags )
357     {
358         this.flags = flags;
359     }
360 
361 
362     /**
363      * @return the key
364      */
365     public EncryptionKey getKey()
366     {
367         return key;
368     }
369 
370 
371     /**
372      * @param key the key to set
373      */
374     public void setKey( EncryptionKey key )
375     {
376         this.key = key;
377     }
378 
379 
380     /**
381      * @return the cRealm
382      */
383     public String getCRealm()
384     {
385         return cRealm;
386     }
387 
388 
389     /**
390      * @param cRealm the cRealm to set
391      */
392     public void setCRealm( String cRealm )
393     {
394         this.cRealm = cRealm;
395     }
396 
397 
398     /**
399      * @return the cName
400      */
401     public PrincipalName getCName()
402     {
403         return cName;
404     }
405 
406 
407     /**
408      * @param cName the cName to set
409      */
410     public void setCName( PrincipalName cName )
411     {
412         this.cName = cName;
413     }
414 
415 
416     /**
417      * @return the transited
418      */
419     public TransitedEncoding getTransited()
420     {
421         return transited;
422     }
423 
424 
425     /**
426      * @param transited the transited to set
427      */
428     public void setTransited( TransitedEncoding transited )
429     {
430         this.transited = transited;
431     }
432 
433 
434     /**
435      * @return the authTime
436      */
437     public KerberosTime getAuthTime()
438     {
439         return authTime;
440     }
441 
442 
443     /**
444      * @param authTime the authTime to set
445      */
446     public void setAuthTime( KerberosTime authTime )
447     {
448         this.authTime = authTime;
449     }
450 
451 
452     /**
453      * @return the startTime
454      */
455     public KerberosTime getStartTime()
456     {
457         return startTime;
458     }
459 
460 
461     /**
462      * @param startTime the startTime to set
463      */
464     public void setStartTime( KerberosTime startTime )
465     {
466         this.startTime = startTime;
467     }
468 
469 
470     /**
471      * @return the endTime
472      */
473     public KerberosTime getEndTime()
474     {
475         return endTime;
476     }
477 
478 
479     /**
480      * @param endTime the endTime to set
481      */
482     public void setEndTime( KerberosTime endTime )
483     {
484         this.endTime = endTime;
485     }
486 
487 
488     /**
489      * @return the renewtill
490      */
491     public KerberosTime getRenewTill()
492     {
493         return renewtill;
494     }
495 
496 
497     /**
498      * @param renewtill the renewtill to set
499      */
500     public void setRenewTill( KerberosTime renewtill )
501     {
502         this.renewtill = renewtill;
503     }
504 
505 
506     /**
507      * @return the clientAddresses
508      */
509     public HostAddresses getClientAddresses()
510     {
511         return clientAddresses;
512     }
513 
514 
515     /**
516      * @param clientAddresses the clientAddresses to set
517      */
518     public void setClientAddresses( HostAddresses clientAddresses )
519     {
520         this.clientAddresses = clientAddresses;
521     }
522 
523 
524     /**
525      * @return the authzData
526      */
527     public AuthorizationData getAuthorizationData()
528     {
529         return authorizationData;
530     }
531 
532 
533     /**
534      * @param authzData the authzData to set
535      */
536     public void setAuthorizationData( AuthorizationData authzData )
537     {
538         this.authorizationData = authzData;
539     }
540 
541 
542     /**
543      * adds the given flag to the already existing flags.
544      * If no flags exist then creates a new TicketFlags object then sets this flag
545      * and assigns the TicketFlags to this ticket part
546      * 
547      * @param flag the flag to be set
548      */
549     public void setFlag( TicketFlag flag )
550     {
551         if ( flags == null )
552         {
553             flags = new TicketFlags();
554         }
555 
556         flags.setFlag( flag.getValue() );
557     }
558 
559 
560     /**
561      * @see Object#toString()
562      */
563     public String toString()
564     {
565         StringBuilder sb = new StringBuilder();
566 
567         sb.append( "EncTicketPart : {\n" );
568 
569         sb.append( "    flags: " ).append( flags ).append( '\n' );
570         sb.append( "    key: " ).append( key ).append( '\n' );
571         sb.append( "    cRealm: " ).append( cRealm ).append( '\n' );
572         sb.append( "    cName: " ).append( cName ).append( '\n' );
573         sb.append( "    transited: " ).append( transited ).append( '\n' );
574         sb.append( "    authTime: " ).append( authTime ).append( '\n' );
575 
576         if ( startTime != null )
577         {
578             sb.append( "    startTime: " ).append( startTime ).append( '\n' );
579         }
580 
581         sb.append( "    endTime: " ).append( endTime ).append( '\n' );
582 
583         if ( renewtill != null )
584         {
585             sb.append( "    renewtill: " ).append( renewtill ).append( '\n' );
586         }
587 
588         if ( clientAddresses != null )
589         {
590             sb.append( "    clientAddresses: " ).append( clientAddresses ).append( '\n' );
591         }
592 
593         if ( authorizationData != null )
594         {
595             sb.append( "    authzData: " ).append( authorizationData ).append( '\n' );
596         }
597 
598         sb.append( "}\n" );
599 
600         return sb.toString();
601     }
602 
603 }