001/*
002 *   Licensed to the Apache Software Foundation (ASF) under one
003 *   or more contributor license agreements.  See the NOTICE file
004 *   distributed with this work for additional information
005 *   regarding copyright ownership.  The ASF licenses this file
006 *   to you under the Apache License, Version 2.0 (the
007 *   "License"); you may not use this file except in compliance
008 *   with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *   Unless required by applicable law or agreed to in writing,
013 *   software distributed under the License is distributed on an
014 *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *   KIND, either express or implied.  See the License for the
016 *   specific language governing permissions and limitations
017 *   under the License.
018 *
019 */
020
021package org.apache.directory.shared.kerberos.components;
022
023
024import java.nio.BufferOverflowException;
025import java.nio.ByteBuffer;
026
027import org.apache.directory.api.asn1.Asn1Object;
028import org.apache.directory.api.asn1.EncoderException;
029import org.apache.directory.api.asn1.ber.tlv.BerValue;
030import org.apache.directory.api.asn1.ber.tlv.TLV;
031import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
032import org.apache.directory.api.util.Strings;
033import org.apache.directory.server.i18n.I18n;
034import org.apache.directory.shared.kerberos.KerberosConstants;
035import org.apache.directory.shared.kerberos.KerberosTime;
036import org.apache.directory.shared.kerberos.flags.TicketFlags;
037import org.slf4j.Logger;
038import org.slf4j.LoggerFactory;
039
040
041/**
042 * KrbCredInfo     ::= SEQUENCE {
043 *      key             [0] EncryptionKey,
044 *      prealm          [1] Realm OPTIONAL,
045 *      pname           [2] PrincipalName OPTIONAL,
046 *      flags           [3] TicketFlags OPTIONAL,
047 *      authtime        [4] KerberosTime OPTIONAL,
048 *      starttime       [5] KerberosTime OPTIONAL,
049 *      endtime         [6] KerberosTime OPTIONAL,
050 *      renew-till      [7] KerberosTime OPTIONAL,
051 *      srealm          [8] Realm OPTIONAL,
052 *      sname           [9] PrincipalName OPTIONAL,
053 *      caddr           [10] HostAddresses OPTIONAL
054 * }
055 *
056 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
057 */
058public class KrbCredInfo implements Asn1Object
059{
060    /** The logger */
061    private static final Logger log = LoggerFactory.getLogger( KrbCredInfo.class );
062
063    /** Speedup for logs */
064    private static final boolean IS_DEBUG = log.isDebugEnabled();
065
066    /** the encryption key */
067    private EncryptionKey key;
068
069    /** principal identity's realm */
070    private String pRealm;
071
072    /** principal identity's name */
073    private PrincipalName pName;
074
075    /** the ticket flags */
076    private TicketFlags ticketFlags;
077
078    /** the time of initial authentication */
079    private KerberosTime authTime;
080
081    /** the time after which the ticket is valid */
082    private KerberosTime startTime;
083
084    /** the expiration time of ticket */
085    private KerberosTime endTime;
086
087    /** the maximum endtime that may be included in a renewal */
088    private KerberosTime renewtill;
089
090    /** searver's realm */
091    private String sRealm;
092
093    /** server's principal name */
094    private PrincipalName sName;
095
096    /** the addresses for which the ticket can be used */
097    private HostAddresses clientAddresses;
098
099    private int keyLen;
100    private int pRealmLen;
101    private byte[] pRealmBytes;
102    private int pNameLen;
103    private int ticketFlagsLen;
104    private int authTimeLen;
105    private byte[] authTimeBytes;
106    private int startTimeLen;
107    private byte[] startTimeBytes;
108    private int endTimeLen;
109    private byte[] endTimeBytes;
110    private int renewtillLen;
111    private byte[] renewtillBytes;
112    private int sRealmLen;
113    private byte[] sRealmBytes;
114    private int sNameLen;
115    private int clientAddressesLen;
116    private int krbKredInfoSeqLen;
117
118
119    /**
120     * Calculate the length od KrbCredInfo:
121     * 
122     * <pre>
123     * 0x30 L1 KrbCredInfo SEQ tag
124     *  |
125     *  |
126     *  +--&gt; 0xA0 L2 key tag
127     *  |     |
128     *  |     +--&gt; 0x30 L2-2 key
129     *  |
130     *  +--&gt; [0xA1 L3 prealm tag
131     *  |      |
132     *  |      +--&gt; 0x1B L3-2 prealm]
133     *  |
134     *  +--&gt; [0xA2 L4 pname tag
135     *  |      |
136     *  |      +--&gt; 0x30 L4-2 pname]
137     *  |
138     *  +--&gt; [0xA3 L5 flags tag
139     *  |      |
140     *  |      +--&gt; 0x02 L5-2 flags]
141     *  |
142     *  +--&gt; [0xA4 0x11 authtime tag
143     *  |      |
144     *  |      +--&gt; 0x18 0x1F authtime]
145     *  |
146     *  +--&gt; [0xA5 0x11 starttime tag
147     *  |      |
148     *  |      +--&gt; 0x18 0x1F starttime]
149     *  |
150     *  +--&gt; [0xA6 0x11 endtime tag
151     *  |      |
152     *  |      +--&gt; 0x18 0x1F endtime]
153     *  |
154     *  +--&gt; [0xA7 0x11 renew-till tag
155     *  |      |
156     *  |      +--&gt; 0x18 0x1F renew-till]
157     *  |
158     *  +--&gt; [0xA8 L6 srealm tag
159     *  |      |
160     *  |      +--&gt; 0x1B L6-2 srealm]
161     *  |
162     *  +--&gt; [0xA9 L7 sname tag
163     *  |      |
164     *  |      +--&gt; 0x30 L7-2 sname]
165     *  |
166     *  +--&gt; [0xAA L8 caddr tag
167     *         |
168     *         +--&gt; 0x30 L8-2 caddr 
169     * </pre>
170     */
171    @Override
172    public int computeLength()
173    {
174        keyLen = key.computeLength();
175        krbKredInfoSeqLen = 1 + TLV.getNbBytes( keyLen ) + keyLen;
176
177        if ( pRealm != null )
178        {
179            pRealmBytes = Strings.getBytesUtf8( pRealm );
180            pRealmLen = 1 + TLV.getNbBytes( pRealmBytes.length ) + pRealmBytes.length;
181            krbKredInfoSeqLen += 1 + TLV.getNbBytes( pRealmLen ) + pRealmLen;
182        }
183
184        if ( pName != null )
185        {
186            pNameLen = pName.computeLength();
187            krbKredInfoSeqLen += 1 + TLV.getNbBytes( pNameLen ) + pNameLen;
188        }
189
190        if ( ticketFlags != null )
191        {
192            ticketFlagsLen = ticketFlags.getData().length;
193            ticketFlagsLen = 1 + TLV.getNbBytes( ticketFlagsLen ) + ticketFlagsLen;
194            krbKredInfoSeqLen += 1 + TLV.getNbBytes( ticketFlagsLen ) + ticketFlagsLen;
195        }
196
197        if ( authTime != null )
198        {
199            authTimeBytes = authTime.getBytes();
200            authTimeLen = 1 + TLV.getNbBytes( authTimeBytes.length ) + authTimeBytes.length;
201            krbKredInfoSeqLen += 1 + TLV.getNbBytes( authTimeLen ) + authTimeLen;
202        }
203
204        if ( startTime != null )
205        {
206            startTimeBytes = startTime.getBytes();
207            startTimeLen = 1 + TLV.getNbBytes( startTimeBytes.length ) + startTimeBytes.length;
208            krbKredInfoSeqLen += 1 + TLV.getNbBytes( startTimeLen ) + startTimeLen;
209        }
210
211        if ( endTime != null )
212        {
213            endTimeBytes = endTime.getBytes();
214            endTimeLen = 1 + TLV.getNbBytes( endTimeBytes.length ) + endTimeBytes.length;
215            krbKredInfoSeqLen += 1 + TLV.getNbBytes( endTimeLen ) + endTimeLen;
216        }
217
218        if ( renewtill != null )
219        {
220            renewtillBytes = renewtill.getBytes();
221            renewtillLen = 1 + TLV.getNbBytes( renewtillBytes.length ) + renewtillBytes.length;
222            krbKredInfoSeqLen += 1 + TLV.getNbBytes( renewtillLen ) + renewtillLen;
223        }
224
225        if ( sRealm != null )
226        {
227            sRealmBytes = Strings.getBytesUtf8( sRealm );
228            sRealmLen = 1 + TLV.getNbBytes( sRealmBytes.length ) + sRealmBytes.length;
229            krbKredInfoSeqLen += 1 + TLV.getNbBytes( sRealmLen ) + sRealmLen;
230        }
231
232        if ( sName != null )
233        {
234            sNameLen = sName.computeLength();
235            krbKredInfoSeqLen += 1 + TLV.getNbBytes( sNameLen ) + sNameLen;
236        }
237
238        if ( clientAddresses != null )
239        {
240            clientAddressesLen = clientAddresses.computeLength();
241            krbKredInfoSeqLen += 1 + TLV.getNbBytes( clientAddressesLen ) + clientAddressesLen;
242        }
243
244        return 1 + TLV.getNbBytes( krbKredInfoSeqLen ) + krbKredInfoSeqLen;
245    }
246
247
248    /**
249     * {@inheritDoc}
250     */
251    @Override
252    public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
253    {
254        if ( buffer == null )
255        {
256            throw new EncoderException( I18n.err( I18n.ERR_148 ) );
257        }
258
259        try
260        {
261            buffer.put( UniversalTag.SEQUENCE.getValue() );
262            buffer.put( TLV.getBytes( krbKredInfoSeqLen ) );
263
264            //key tag and value
265            buffer.put( ( byte ) KerberosConstants.KRB_CRED_INFO_KEY_TAG );
266            buffer.put( TLV.getBytes( keyLen ) );
267            key.encode( buffer );
268
269            if ( pRealm != null )
270            {
271                // prealm tag and value
272                buffer.put( ( byte ) KerberosConstants.KRB_CRED_INFO_PREALM_TAG );
273                buffer.put( TLV.getBytes( pRealmLen ) );
274
275                buffer.put( UniversalTag.GENERAL_STRING.getValue() );
276                buffer.put( TLV.getBytes( pRealmBytes.length ) );
277                buffer.put( pRealmBytes );
278            }
279
280            if ( pName != null )
281            {
282                // pname tag and value
283                buffer.put( ( byte ) KerberosConstants.KRB_CRED_INFO_PNAME_TAG );
284                buffer.put( TLV.getBytes( pNameLen ) );
285                pName.encode( buffer );
286            }
287
288            if ( ticketFlags != null )
289            {
290                // flags tag and value
291                buffer.put( ( byte ) KerberosConstants.KRB_CRED_INFO_FLAGS_TAG );
292                buffer.put( TLV.getBytes( ticketFlagsLen ) );
293                BerValue.encode( buffer, ticketFlags );
294            }
295
296            if ( authTime != null )
297            {
298                // authtime tag and value
299                buffer.put( ( byte ) KerberosConstants.KRB_CRED_INFO_AUTHTIME_TAG );
300                buffer.put( TLV.getBytes( authTimeLen ) );
301
302                buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
303                buffer.put( ( byte ) 0x0F );
304                buffer.put( authTimeBytes );
305            }
306
307            if ( startTime != null )
308            {
309                // starttime tag and value
310                buffer.put( ( byte ) KerberosConstants.KRB_CRED_INFO_STARTTIME_TAG );
311                buffer.put( TLV.getBytes( startTimeLen ) );
312
313                buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
314                buffer.put( ( byte ) 0x0F );
315                buffer.put( startTimeBytes );
316            }
317
318            if ( endTime != null )
319            {
320                // endtime tag and value
321                buffer.put( ( byte ) KerberosConstants.KRB_CRED_INFO_ENDTIME_TAG );
322                buffer.put( TLV.getBytes( endTimeLen ) );
323
324                buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
325                buffer.put( ( byte ) 0x0F );
326                buffer.put( endTimeBytes );
327            }
328
329            if ( renewtill != null )
330            {
331                // renewtill tag and value
332                buffer.put( ( byte ) KerberosConstants.KRB_CRED_INFO_RENEWTILL_TAG );
333                buffer.put( TLV.getBytes( renewtillLen ) );
334
335                buffer.put( UniversalTag.GENERALIZED_TIME.getValue() );
336                buffer.put( ( byte ) 0x0F );
337                buffer.put( renewtillBytes );
338            }
339
340            if ( sRealm != null )
341            {
342                // srealm tag and value
343                buffer.put( ( byte ) KerberosConstants.KRB_CRED_INFO_SREALM_TAG );
344                buffer.put( TLV.getBytes( sRealmLen ) );
345
346                buffer.put( UniversalTag.GENERAL_STRING.getValue() );
347                buffer.put( TLV.getBytes( sRealmBytes.length ) );
348                buffer.put( sRealmBytes );
349            }
350
351            if ( sName != null )
352            {
353                // sname tag and value
354                buffer.put( ( byte ) KerberosConstants.KRB_CRED_INFO_SNAME_TAG );
355                buffer.put( TLV.getBytes( sNameLen ) );
356                sName.encode( buffer );
357            }
358
359            if ( clientAddresses != null )
360            {
361                // caddr tag and value
362                buffer.put( ( byte ) KerberosConstants.KRB_CRED_INFO_CADDR_TAG );
363                buffer.put( TLV.getBytes( clientAddressesLen ) );
364                clientAddresses.encode( buffer );
365            }
366        }
367        catch ( BufferOverflowException boe )
368        {
369            log.error( I18n.err( I18n.ERR_739_CANNOT_ENCODE_KRB_CRED_INFO, 1 + TLV.getNbBytes( krbKredInfoSeqLen )
370                + krbKredInfoSeqLen, buffer.capacity() ) );
371            throw new EncoderException( I18n.err( I18n.ERR_138 ), boe );
372        }
373
374        if ( IS_DEBUG )
375        {
376            log.debug( "KrbCredInfo encoding : {}", Strings.dumpBytes( buffer.array() ) );
377            log.debug( "KrbCredInfo initial value : {}", this );
378        }
379
380        return buffer;
381    }
382
383
384    /**
385     * @return the key
386     */
387    public EncryptionKey getKey()
388    {
389        return key;
390    }
391
392
393    /**
394     * @param key the key to set
395     */
396    public void setKey( EncryptionKey key )
397    {
398        this.key = key;
399    }
400
401
402    /**
403     * @return the pRealm
404     */
405    public String getpRealm()
406    {
407        return pRealm;
408    }
409
410
411    /**
412     * @param pRealm the pRealm to set
413     */
414    public void setpRealm( String pRealm )
415    {
416        this.pRealm = pRealm;
417    }
418
419
420    /**
421     * @return the pName
422     */
423    public PrincipalName getpName()
424    {
425        return pName;
426    }
427
428
429    /**
430     * @param pName the pName to set
431     */
432    public void setpName( PrincipalName pName )
433    {
434        this.pName = pName;
435    }
436
437
438    /**
439     * @return the ticketFlags
440     */
441    public TicketFlags getTicketFlags()
442    {
443        return ticketFlags;
444    }
445
446
447    /**
448     * @param ticketFlags the ticketFlags to set
449     */
450    public void setTicketFlags( TicketFlags ticketFlags )
451    {
452        this.ticketFlags = ticketFlags;
453    }
454
455
456    /**
457     * @return the authTime
458     */
459    public KerberosTime getAuthTime()
460    {
461        return authTime;
462    }
463
464
465    /**
466     * @param authTime the authTime to set
467     */
468    public void setAuthTime( KerberosTime authTime )
469    {
470        this.authTime = authTime;
471    }
472
473
474    /**
475     * @return the startTime
476     */
477    public KerberosTime getStartTime()
478    {
479        return startTime;
480    }
481
482
483    /**
484     * @param startTime the startTime to set
485     */
486    public void setStartTime( KerberosTime startTime )
487    {
488        this.startTime = startTime;
489    }
490
491
492    /**
493     * @return the endTime
494     */
495    public KerberosTime getEndTime()
496    {
497        return endTime;
498    }
499
500
501    /**
502     * @param endTime the endTime to set
503     */
504    public void setEndTime( KerberosTime endTime )
505    {
506        this.endTime = endTime;
507    }
508
509
510    /**
511     * @return the renewtill
512     */
513    public KerberosTime getRenewtill()
514    {
515        return renewtill;
516    }
517
518
519    /**
520     * @param renewtill the renewtill to set
521     */
522    public void setRenewtill( KerberosTime renewtill )
523    {
524        this.renewtill = renewtill;
525    }
526
527
528    /**
529     * @return the sRealm
530     */
531    public String getsRealm()
532    {
533        return sRealm;
534    }
535
536
537    /**
538     * @param sRealm the sRealm to set
539     */
540    public void setsRealm( String sRealm )
541    {
542        this.sRealm = sRealm;
543    }
544
545
546    /**
547     * @return the sName
548     */
549    public PrincipalName getsName()
550    {
551        return sName;
552    }
553
554
555    /**
556     * @param sName the sName to set
557     */
558    public void setsName( PrincipalName sName )
559    {
560        this.sName = sName;
561    }
562
563
564    /**
565     * @return the clientAddresses
566     */
567    public HostAddresses getClientAddresses()
568    {
569        return clientAddresses;
570    }
571
572
573    /**
574     * @param clientAddresses the clientAddresses to set
575     */
576    public void setClientAddresses( HostAddresses clientAddresses )
577    {
578        this.clientAddresses = clientAddresses;
579    }
580
581
582    /**
583     * @see Object#toString()
584     */
585    public String toString()
586    {
587        StringBuilder sb = new StringBuilder();
588
589        sb.append( "KrbCredInfo : {\n" );
590        sb.append( "    key: " ).append( key ).append( '\n' );
591
592        if ( pRealm != null )
593        {
594            sb.append( "    pRealm: " ).append( pRealm ).append( '\n' );
595        }
596
597        if ( pName != null )
598        {
599            sb.append( "    pName: " ).append( pName ).append( '\n' );
600        }
601
602        if ( ticketFlags != null )
603        {
604            sb.append( "    ticketFlags: " ).append( ticketFlags ).append( '\n' );
605        }
606
607        if ( authTime != null )
608        {
609            sb.append( "    authTime: " ).append( authTime ).append( '\n' );
610        }
611
612        if ( startTime != null )
613        {
614            sb.append( "    startTime: " ).append( startTime ).append( '\n' );
615        }
616
617        if ( endTime != null )
618        {
619            sb.append( "    endTime: " ).append( endTime ).append( '\n' );
620        }
621
622        if ( renewtill != null )
623        {
624            sb.append( "    renewtill: " ).append( renewtill ).append( '\n' );
625        }
626
627        if ( sRealm != null )
628        {
629            sb.append( "    sRealm: " ).append( sRealm ).append( '\n' );
630        }
631
632        if ( sName != null )
633        {
634            sb.append( "    sName: " ).append( sName ).append( '\n' );
635        }
636
637        if ( clientAddresses != null )
638        {
639            sb.append( "    clientAddresses: " ).append( clientAddresses ).append( '\n' );
640        }
641
642        sb.append( "}\n" );
643
644        return sb.toString();
645
646    }
647}