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  package org.apache.directory.shared.kerberos.components;
21  
22  
23  import java.nio.BufferOverflowException;
24  import java.nio.ByteBuffer;
25  
26  import org.apache.directory.api.asn1.Asn1Object;
27  import org.apache.directory.api.asn1.EncoderException;
28  import org.apache.directory.api.asn1.ber.tlv.BerValue;
29  import org.apache.directory.api.asn1.ber.tlv.TLV;
30  import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
31  import org.apache.directory.api.util.Strings;
32  import org.apache.directory.server.i18n.I18n;
33  import org.apache.directory.shared.kerberos.KerberosConstants;
34  import org.apache.directory.shared.kerberos.KerberosTime;
35  import org.apache.directory.shared.kerberos.flags.TicketFlags;
36  import org.slf4j.Logger;
37  import org.slf4j.LoggerFactory;
38  
39  
40  /**
41   * Base class for encrypted parts of KDC responses.
42   * 
43   * The ASN.1 grammar for this structure is :
44   * <pre>
45   * EncKDCRepPart   ::= SEQUENCE {
46   *         key             [0] EncryptionKey,
47   *         last-req        [1] LastReq,
48   *         nonce           [2] UInt32,
49   *         key-expiration  [3] KerberosTime OPTIONAL,
50   *         flags           [4] TicketFlags,
51   *         authtime        [5] KerberosTime,
52   *         starttime       [6] KerberosTime OPTIONAL,
53   *         endtime         [7] KerberosTime,
54   *         renew-till      [8] KerberosTime OPTIONAL,
55   *         srealm          [9] Realm,
56   *         sname           [10] PrincipalName,
57   *         caddr           [11] HostAddresses OPTIONAL
58   * }
59   * </pre>
60   * 
61   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
62   */
63  public class EncKdcRepPart implements Asn1Object
64  {
65      /** The logger */
66      private static final Logger log = LoggerFactory.getLogger( EncKdcRepPart.class );
67  
68      /** Speedup for logs */
69      private static final boolean IS_DEBUG = log.isDebugEnabled();
70  
71      /** The encryption key */
72      private EncryptionKey key;
73  
74      /** The time of the last request */
75      private LastReq lastReq;
76  
77      /** The nonce */
78      private int nonce;
79  
80      /** The KeyExpiration */
81      private KerberosTime keyExpiration; //optional
82  
83      /** The Ticket flags */
84      private TicketFlagsd/kerberos/flags/TicketFlags.html#TicketFlags">TicketFlags flags = new TicketFlags();
85  
86      /** The initial Authentication time */
87      private KerberosTime authTime;
88  
89      /** The ticket's start time */
90      private KerberosTime startTime; //optional
91  
92      /** The Ticket expiration time */
93      private KerberosTime endTime;
94  
95      /** Maximum endtime in a renewal */
96      private KerberosTime renewTill; //optional
97  
98      /** The server's realm */
99      private String srealm;
100 
101     /** The server's principal */
102     private PrincipalName sname;
103 
104     /** The client addresses */
105     private HostAddresses caddr; //optional
106 
107     // Storage for computed lengths
108     private int keyLength;
109     private int lastReqLength;
110     private int nonceLength;
111     private int flagsLength;
112     private byte[] srealmBytes;
113     private int srealmLength;
114     private int snameLength;
115     private int caddrLength;
116     private int encKdcRepPartSeqLength;
117 
118 
119     /**
120      * Creates a new instance of EncKdcRepPart.
121      */
122     public EncKdcRepPart()
123     {
124     }
125 
126 
127     /**
128      * Returns the auth {@link KerberosTime}.
129      *
130      * @return The auth {@link KerberosTime}.
131      */
132     public KerberosTime getAuthTime()
133     {
134         return authTime;
135     }
136 
137 
138     /**
139      * Sets the auth {@link KerberosTime}.
140      *
141      * @param time
142      */
143     public void setAuthTime( KerberosTime time )
144     {
145         authTime = time;
146     }
147 
148 
149     /**
150      * Returns the client {@link HostAddresses}.
151      *
152      * @return The client {@link HostAddresses}.
153      */
154     public HostAddresses getClientAddresses()
155     {
156         return caddr;
157     }
158 
159 
160     /**
161      * Sets the client {@link HostAddresses}.
162      *
163      * @param caddr The client addresses
164      */
165     public void setClientAddresses( HostAddresses caddr )
166     {
167         this.caddr = caddr;
168     }
169 
170 
171     /**
172      * Returns the end {@link KerberosTime}.
173      *
174      * @return The end {@link KerberosTime}.
175      */
176     public KerberosTime getEndTime()
177     {
178         return endTime;
179     }
180 
181 
182     /**
183      * Sets the end {@link KerberosTime}.
184      *
185      * @param time
186      */
187     public void setEndTime( KerberosTime time )
188     {
189         endTime = time;
190     }
191 
192 
193     /**
194      * Returns the {@link TicketFlags}.
195      *
196      * @return The {@link TicketFlags}.
197      */
198     public TicketFlags getFlags()
199     {
200         return flags;
201     }
202 
203 
204     /**
205      * Sets the {@link TicketFlags}.
206      *
207      * @param flags
208      */
209     public void setFlags( TicketFlags flags )
210     {
211         this.flags = flags;
212     }
213 
214 
215     /**
216      * Returns the {@link EncryptionKey}.
217      *
218      * @return The {@link EncryptionKey}.
219      */
220     public EncryptionKey getKey()
221     {
222         return key;
223     }
224 
225 
226     /**
227      * Sets the {@link EncryptionKey}.
228      *
229      * @param key
230      */
231     public void setKey( EncryptionKey key )
232     {
233         this.key = key;
234     }
235 
236 
237     /**
238      * Returns the key expiration {@link KerberosTime}.
239      *
240      * @return The key expiration {@link KerberosTime}.
241      */
242     public KerberosTime getKeyExpiration()
243     {
244         return keyExpiration;
245     }
246 
247 
248     /**
249      * Sets the key expiration {@link KerberosTime}.
250      *
251      * @param expiration
252      */
253     public void setKeyExpiration( KerberosTime expiration )
254     {
255         keyExpiration = expiration;
256     }
257 
258 
259     /**
260      * Returns the {@link LastReq}.
261      *
262      * @return The {@link LastReq}.
263      */
264     public LastReq getLastReq()
265     {
266         return lastReq;
267     }
268 
269 
270     /**
271      * Sets the {@link LastReq}.
272      *
273      * @param lastReq The LastReq to set
274      */
275     public void setLastReq( LastReq lastReq )
276     {
277         this.lastReq = lastReq;
278     }
279 
280 
281     /**
282      * Returns the nonce.
283      *
284      * @return The nonce.
285      */
286     public int getNonce()
287     {
288         return nonce;
289     }
290 
291 
292     /**
293      * Sets the nonce.
294      *
295      * @param nonce
296      */
297     public void setNonce( int nonce )
298     {
299         this.nonce = nonce;
300     }
301 
302 
303     /**
304      * Returns the renew till {@link KerberosTime}.
305      *
306      * @return The renew till {@link KerberosTime}.
307      */
308     public KerberosTime getRenewTill()
309     {
310         return renewTill;
311     }
312 
313 
314     /**
315      * Sets the renew till {@link KerberosTime}.
316      *
317      * @param till
318      */
319     public void setRenewTill( KerberosTime till )
320     {
321         renewTill = till;
322     }
323 
324 
325     /**
326      * Returns the server {@link PrincipalName}.
327      *
328      * @return The server {@link PrincipalName}.
329      */
330     public PrincipalName getSName()
331     {
332         return sname;
333     }
334 
335 
336     /**
337      * Sets the server {@link PrincipalName}.
338      *
339      * @param sname The server PrincipalName
340      */
341     public void setSName( PrincipalName sname )
342     {
343         this.sname = sname;
344     }
345 
346 
347     /**
348      * Returns the server realm.
349      *
350      * @return The server realm.
351      */
352     public String getSRealm()
353     {
354         return srealm;
355     }
356 
357 
358     /**
359      * Sets the server realm.
360      *
361      * @param srealm The server realm
362      */
363     public void setSRealm( String srealm )
364     {
365         this.srealm = srealm;
366     }
367 
368 
369     /**
370      * Returns the start {@link KerberosTime}.
371      *
372      * @return The start {@link KerberosTime}.
373      */
374     public KerberosTime getStartTime()
375     {
376         return startTime;
377     }
378 
379 
380     /**
381      * Sets the start {@link KerberosTime}.
382      *
383      * @param time he start time to set
384      */
385     public void setStartTime( KerberosTime time )
386     {
387         startTime = time;
388     }
389 
390 
391     /**
392      * Compute the EncKdcRepPart length
393      * <pre>
394      * EncKdcRepPart :
395      * 
396      * 0x30 L1 EncKdcRepPart sequence
397      *  |
398      *  +--&gt; 0xA0 L2 key tag
399      *  |     |
400      *  |     +--&gt; 0x30 L2-1 key ( EncryptionKey)
401      *  |
402      *  +--&gt; 0xA1 L3 last-req tag
403      *  |     |
404      *  |     +--&gt; 0x30 L3-1 last-req ( LastReq )
405      *  |     
406      *  +--&gt; 0xA2 L4 nonce tag
407      *  |     |
408      *  |     +--&gt; 0x02 L4-1 nonce (Int)
409      *  |     
410      * [+--&gt; 0xA3 0x11 key-expiration tag]
411      *  |     |
412      *  |     +--&gt; 0x18 0x0F key-expiration ( KerberosTime )
413      *  |     
414      *  +--&gt; 0xA4 0x07 flags tag 
415      *  |     |
416      *  |     +--&gt; 0x03 0x05 flags ( TicketFlags )
417      *  |     
418      *  +--&gt; 0xA5 0x11 authtime tag
419      *  |     |
420      *  |     +--&gt; 0x18 0x0F authtime ( KerberosTime )
421      *  |     
422      * [+--&gt; 0xA6 0x11 starttime tag]
423      *  |     |
424      *  |     +--&gt; 0x18 0x0F starttime ( KerberosTime )
425      *  |     
426      *  +--&gt; 0xA7 0x11 endtime tag
427      *  |     |
428      *  |     +--&gt; 0x18 0x0F endtime ( KerberosTime )
429      *  |     
430      * [+--&gt; 0xA8 0x11 renew-till tag]
431      *  |     |
432      *  |     +--&gt; 0x18 0x0F renew-till ( KerberosTime )
433      *  |     
434      *  +--&gt; 0xA9 L5 srealm tag
435      *  |     |
436      *  |     +--&gt; 0x1B L5-1 srealm ( KerberosString )
437      *  |     
438      *  +--&gt; 0xAA L6 sname tag
439      *  |     |
440      *  |     +--&gt; 0x30 L6-1 sname ( PrincipalName )
441      *  |     
442      * [+--&gt; 0xAB L7 caddr tag]
443      *        |
444      *        +--&gt; 0x30 L7-1 caddr ( HostAddresses )
445      *  </pre>
446      */
447     public int computeLength()
448     {
449         // The key
450         keyLength = key.computeLength();
451         encKdcRepPartSeqLength = 1 + TLV.getNbBytes( keyLength ) + keyLength;
452 
453         // The last-req
454         lastReqLength = lastReq.computeLength();
455         encKdcRepPartSeqLength += 1 + TLV.getNbBytes( lastReqLength ) + lastReqLength;
456 
457         // The nonce
458         nonceLength = BerValue.getNbBytes( nonce );
459         nonceLength = 1 + TLV.getNbBytes( nonceLength ) + nonceLength;
460         encKdcRepPartSeqLength += 1 + TLV.getNbBytes( nonceLength ) + nonceLength;
461 
462         // The keyExpiration
463         if ( keyExpiration != null )
464         {
465             encKdcRepPartSeqLength += 1 + 1 + 0x11;
466         }
467 
468         // The flags
469         flagsLength = 1 + 1 + 5;
470         encKdcRepPartSeqLength += 1 + TLV.getNbBytes( flagsLength ) + flagsLength;
471 
472         // The authtime
473         encKdcRepPartSeqLength += 1 + 1 + 0x11;
474 
475         // The starttime, if any
476         if ( startTime != null )
477         {
478             encKdcRepPartSeqLength += 1 + 1 + 0x11;
479         }
480 
481         // The endtime
482         encKdcRepPartSeqLength += 1 + 1 + 0x11;
483 
484         // The renew-till, if any
485         if ( renewTill != null )
486         {
487             encKdcRepPartSeqLength += 1 + 1 + 0x11;
488         }
489 
490         // The srealm
491         srealmBytes = Strings.getBytesUtf8( srealm );
492         srealmLength = 1 + TLV.getNbBytes( srealmBytes.length ) + srealmBytes.length;
493         encKdcRepPartSeqLength += 1 + TLV.getNbBytes( srealmLength ) + srealmLength;
494 
495         // The sname
496         snameLength = sname.computeLength();
497         encKdcRepPartSeqLength += 1 + TLV.getNbBytes( snameLength ) + snameLength;
498 
499         // The caddr if any
500         if ( caddr != null )
501         {
502             caddrLength = caddr.computeLength();
503             encKdcRepPartSeqLength += 1 + TLV.getNbBytes( caddrLength ) + caddrLength;
504         }
505 
506         return 1 + TLV.getNbBytes( encKdcRepPartSeqLength ) + encKdcRepPartSeqLength;
507     }
508 
509 
510     /**
511      * Encode the EncKdcRepPart message to a PDU. 
512      * 
513      * @param buffer The buffer where to put the PDU. It should have been allocated
514      * before, with the right size.
515      * @return The constructed PDU.
516      */
517     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
518     {
519         if ( buffer == null )
520         {
521             throw new EncoderException( I18n.err( I18n.ERR_148 ) );
522         }
523 
524         try
525         {
526             // The EncKdcRepPart sequence
527             buffer.put( UniversalTag.SEQUENCE.getValue() );
528             buffer.put( TLV.getBytes( encKdcRepPartSeqLength ) );
529 
530             // The Key
531             buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_KEY_TAG );
532             buffer.put( TLV.getBytes( keyLength ) );
533             key.encode( buffer );
534 
535             // The LastReq
536             buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_LAST_REQ_TAG );
537             buffer.put( TLV.getBytes( lastReqLength ) );
538             lastReq.encode( buffer );
539 
540             // The nonce
541             buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_NONCE_TAG );
542             buffer.put( TLV.getBytes( nonceLength ) );
543             BerValue.encode( buffer, nonce );
544 
545             // The key-expiration, if any
546             if ( keyExpiration != null )
547             {
548                 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_KEY_EXPIRATION_TAG );
549                 buffer.put( TLV.getBytes( 0x11 ) );
550 
551                 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
552                 buffer.put( ( byte ) 0x0F );
553                 buffer.put( keyExpiration.getBytes() );
554             }
555 
556             // The flags
557             buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_FLAGS_TAG );
558             buffer.put( TLV.getBytes( 0x07 ) );
559             BerValue.encode( buffer, flags );
560 
561             // The authtime
562             buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_AUTH_TIME_TAG );
563             buffer.put( TLV.getBytes( 0x11 ) );
564             buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
565             buffer.put( ( byte ) 0x0F );
566             buffer.put( authTime.getBytes() );
567 
568             // The starttime if any
569             if ( startTime != null )
570             {
571                 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_START_TIME_TAG );
572                 buffer.put( TLV.getBytes( 0x11 ) );
573                 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
574                 buffer.put( ( byte ) 0x0F );
575                 buffer.put( startTime.getBytes() );
576             }
577 
578             // The endtime
579             buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_END_TIME_TAG );
580             buffer.put( TLV.getBytes( 0x11 ) );
581             buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
582             buffer.put( ( byte ) 0x0F );
583             buffer.put( endTime.getBytes() );
584 
585             // The renew-till if any
586             if ( renewTill != null )
587             {
588                 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_RENEW_TILL_TAG );
589                 buffer.put( TLV.getBytes( 0x11 ) );
590                 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
591                 buffer.put( ( byte ) 0x0F );
592                 buffer.put( renewTill.getBytes() );
593             }
594 
595             // The srealm
596             buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_SREALM_TAG );
597             buffer.put( TLV.getBytes( srealmLength ) );
598             buffer.put( UniversalTag.GENERAL_STRING.getValue() );
599             buffer.put( TLV.getBytes( srealmBytes.length ) );
600             buffer.put( srealmBytes );
601 
602             // The sname
603             buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_SNAME_TAG );
604             buffer.put( TLV.getBytes( snameLength ) );
605             sname.encode( buffer );
606 
607             // The caddr if any
608             if ( caddr != null )
609             {
610                 buffer.put( ( byte ) KerberosConstants.ENC_KDC_REP_PART_CADDR_TAG );
611                 buffer.put( TLV.getBytes( caddrLength ) );
612                 caddr.encode( buffer );
613             }
614         }
615         catch ( BufferOverflowException boe )
616         {
617             log.error( I18n.err( I18n.ERR_140, 1 + TLV.getNbBytes( 0 ) + 0,
618                 buffer.capacity() ) );
619             throw new EncoderException( I18n.err( I18n.ERR_138 ), boe );
620         }
621 
622         if ( IS_DEBUG )
623         {
624             log.debug( "EncKdcRepPart encoding : {}", Strings.dumpBytes( buffer.array() ) );
625             log.debug( "EncKdcRepPart initial value : {}", this );
626         }
627 
628         return buffer;
629     }
630 
631 
632     /**
633      * @see Object#toString()
634      */
635     public String toString()
636     {
637         StringBuilder sb = new StringBuilder();
638 
639         sb.append( "EncKdcRepPart : \n" );
640         sb.append( "    key : " ).append( key ).append( "\n" );
641         sb.append( "    last-req : " ).append( lastReq ).append( "\n" );
642         sb.append( "    nonce : " ).append( nonce ).append( "\n" );
643 
644         if ( keyExpiration != null )
645         {
646             sb.append( "    key-expiration : " ).append( keyExpiration ).append( "\n" );
647         }
648 
649         sb.append( "    flags : " ).append( flags ).append( "\n" );
650         sb.append( "    authtime : " ).append( authTime ).append( "\n" );
651 
652         if ( startTime != null )
653         {
654             sb.append( "    starttime : " ).append( startTime ).append( "\n" );
655         }
656 
657         sb.append( "    endtime : " ).append( endTime ).append( "\n" );
658 
659         if ( renewTill != null )
660         {
661             sb.append( "    renew-till : " ).append( renewTill ).append( "\n" );
662         }
663 
664         sb.append( "    srealm : " ).append( srealm ).append( "\n" );
665         sb.append( "    sname : " ).append( sname ).append( "\n" );
666 
667         if ( caddr != null )
668         {
669             sb.append( "    caddr : " ).append( caddr ).append( "\n" );
670         }
671 
672         return sb.toString();
673     }
674 }