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.messages;
22  
23  
24  import java.nio.BufferOverflowException;
25  import java.nio.ByteBuffer;
26  
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.KerberosMessageType;
35  import org.apache.directory.shared.kerberos.components.EncryptedData;
36  import org.slf4j.Logger;
37  import org.slf4j.LoggerFactory;
38  
39  
40  /**
41   * Class representing KRB-PRIV message
42   * 
43   * <pre>
44   * KRB-PRIV        ::= [APPLICATION 21] SEQUENCE {
45   *      pvno            [0] INTEGER (5),
46   *      msg-type        [1] INTEGER (21),
47   *                      -- NOTE: there is no [2] tag
48   *      enc-part        [3] EncryptedData -- EncKrbPrivPart
49   * }
50   * </pre>
51   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
52   */
53  public class KrbPriv extends KerberosMessage
54  {
55      /** The logger */
56      private static final Logger log = LoggerFactory.getLogger( KrbError.class );
57  
58      /** Speedup for logs */
59      private static final boolean IS_DEBUG = log.isDebugEnabled();
60  
61      /** the encrypted EncKrbPrivPart component */
62      private EncryptedData encPart;
63  
64      // Storage for computed lengths
65      private int pvnoLen;
66      private int msgTypeLength;
67      private int encPartLen;
68      private int krbPrivSeqLen;
69      private int krbPrivLen;
70  
71  
72      /**
73       * Creates a new instance of KrbPriv.
74       */
75      public KrbPriv()
76      {
77          super( 5, KerberosMessageType.KRB_PRIV );
78      }
79  
80  
81      /**
82       * @return the encPart
83       */
84      public EncryptedData getEncPart()
85      {
86          return encPart;
87      }
88  
89  
90      /**
91       * @param encPart the encPart to set
92       */
93      public void setEncPart( EncryptedData encPart )
94      {
95          this.encPart = encPart;
96      }
97  
98  
99      /**
100      * Compute the KRB-PRIV length
101      * <pre>
102      * KRB-PRIV :
103      * 
104      * 0x75 L1 KRB-PRIV APPLICATION[21]
105      *  |
106      *  +--&gt; 0x30 L2 KRB-PRIV sequence
107      *        |
108      *        +--&gt; 0xA0 0x03 pvno tag
109      *        |     |
110      *        |     +--&gt; 0x02 0x01 0x05 pvno (5)
111      *        |
112      *        +--&gt; 0xA1 0x03 msg-type tag
113      *        |     |
114      *        |     +--&gt; 0x02 0x01 0x15 msg-type (21)
115      *        |     
116      *        +--&gt; 0xA3 L3 enc-part (EncryptedData -- EncKrbPrivPart)
117      * </pre>
118      */
119     @Override
120     public int computeLength()
121     {
122         pvnoLen = 1 + 1 + 1;
123         krbPrivSeqLen = 1 + TLV.getNbBytes( pvnoLen ) + pvnoLen;
124 
125         msgTypeLength = 1 + 1 + BerValue.getNbBytes( getMessageType().getValue() );
126         krbPrivSeqLen += 1 + TLV.getNbBytes( msgTypeLength ) + msgTypeLength;
127 
128         encPartLen = encPart.computeLength();
129         krbPrivSeqLen += 1 + TLV.getNbBytes( encPartLen ) + encPartLen;
130 
131         krbPrivLen += 1 + TLV.getNbBytes( krbPrivSeqLen ) + krbPrivSeqLen;
132 
133         return 1 + TLV.getNbBytes( krbPrivLen ) + krbPrivLen;
134     }
135 
136 
137     /**
138      * {@inheritDoc}
139      */
140     @Override
141     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
142     {
143         if ( buffer == null )
144         {
145             throw new EncoderException( I18n.err( I18n.ERR_148 ) );
146         }
147 
148         try
149         {
150             // The KRB-SAFE APPLICATION tag
151             buffer.put( ( byte ) KerberosConstants.KRB_PRIV_TAG );
152             buffer.put( TLV.getBytes( krbPrivLen ) );
153 
154             // The KRB-SAFE sequence
155             buffer.put( UniversalTag.SEQUENCE.getValue() );
156             buffer.put( TLV.getBytes( krbPrivSeqLen ) );
157 
158             // pvno tag and value
159             buffer.put( ( byte ) KerberosConstants.KRB_PRIV_PVNO_TAG );
160             buffer.put( TLV.getBytes( pvnoLen ) );
161             BerValue.encode( buffer, getProtocolVersionNumber() );
162 
163             // msg-type tag and value
164             buffer.put( ( byte ) KerberosConstants.KRB_PRIV_MSGTYPE_TAG );
165             buffer.put( TLV.getBytes( msgTypeLength ) );
166             BerValue.encode( buffer, getMessageType().getValue() );
167 
168             // enc-part
169             buffer.put( ( byte ) KerberosConstants.KRB_PRIV_ENC_PART_TAG );
170             buffer.put( TLV.getBytes( encPartLen ) );
171             encPart.encode( buffer );
172         }
173         catch ( BufferOverflowException boe )
174         {
175             log.error( I18n.err( I18n.ERR_738_CANNOT_ENCODE_KRB_PRIV, 1 + TLV.getNbBytes( krbPrivLen )
176                 + krbPrivLen, buffer.capacity() ) );
177             throw new EncoderException( I18n.err( I18n.ERR_138 ), boe );
178         }
179 
180         if ( IS_DEBUG )
181         {
182             log.debug( "KrbPriv encoding : {}", Strings.dumpBytes( buffer.array() ) );
183             log.debug( "KrbPriv initial value : {}", this );
184         }
185 
186         return buffer;
187     }
188 
189 
190     /**
191      * @see Object#toString()
192      */
193     public String toString()
194     {
195         StringBuilder sb = new StringBuilder();
196 
197         sb.append( "KRB-PRIV : {\n" );
198         sb.append( "    pvno: " ).append( getProtocolVersionNumber() ).append( '\n' );
199         sb.append( "    msgType: " ).append( getMessageType() ).append( '\n' );
200         sb.append( "    msgType: " ).append( getEncPart() ).append( '\n' );
201         sb.append( "}\n" );
202 
203         return sb.toString();
204     }
205 }