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.codec.types.AuthorizationType;
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  
41  
42  /**
43   * A structure to hold the authorization data.
44   * 
45   * <pre>
46   * AuthorizationData      ::= SEQUENCE OF SEQUENCE {
47   *               ad-type  [0] Int32,
48   *               ad-data  [1] OCTET STRING
49   * }
50   *</pre>
51   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
52   */
53  public class AuthorizationData implements Asn1Object
54  {
55      /** The list of AuthorizationData elements */
56      private List<AuthorizationDataEntry> authorizationData = new ArrayList<>();
57  
58      /** The current AD being processed */
59      private AuthorizationDataEntry currentAD;
60  
61      /** The logger */
62      private static final Logger LOG = LoggerFactory.getLogger( EncryptedData.class );
63  
64      /** Speedup for logs */
65      private static final boolean IS_DEBUG = LOG.isDebugEnabled();
66  
67      // Storage for computed lengths
68      private int adTypeTagLen[];
69      private int adDataTagLen[];
70      private int authorizationDataSeqLen[];
71      private int authorizationDataSeqSeqLen;
72  
73  
74      /**
75       * Creates a new set of AuthorizationData
76       */
77      public AuthorizationData()
78      {
79      }
80  
81  
82      /**
83       * Compute the AuthorizationData length
84       * <pre>
85       * 0x30 L1 AuthorizationData sequence
86       *  |
87       *  +-- 0x30 L2 The AD sequence
88       *       |
89       *       +--&gt; 0xA0 L3 adType tag
90       *       |     |
91       *       |     +--&gt; 0x02 L3-1 adType (int)
92       *       |
93       *       +--&gt; 0xA1 L4 adData tag
94       *             |
95       *             +--&gt; 0x04 L4-1 adData (OCTET STRING)
96       * </pre>
97       */
98      @Override
99      public int computeLength()
100     {
101         int i = 0;
102         authorizationDataSeqLen = new int[authorizationData.size()];
103         adTypeTagLen = new int[authorizationData.size()];
104         adDataTagLen = new int[authorizationData.size()];
105         authorizationDataSeqSeqLen = 0;
106 
107         for ( AuthorizationDataEntry ad : authorizationData )
108         {
109             int adTypeLen = BerValue.getNbBytes( ad.getAdType().getValue() );
110             adTypeTagLen[i] = 1 + TLV.getNbBytes( adTypeLen ) + adTypeLen;
111             adDataTagLen[i] = 1 + TLV.getNbBytes( ad.getAdDataRef().length ) + ad.getAdDataRef().length;
112 
113             authorizationDataSeqLen[i] = 1 + TLV.getNbBytes( adTypeTagLen[i] ) + adTypeTagLen[i] +
114                 1 + TLV.getNbBytes( adDataTagLen[i] ) + adDataTagLen[i];
115 
116             authorizationDataSeqSeqLen += 1 + TLV.getNbBytes( authorizationDataSeqLen[i] ) + authorizationDataSeqLen[i];
117             i++;
118         }
119 
120         return 1 + TLV.getNbBytes( authorizationDataSeqSeqLen ) + authorizationDataSeqSeqLen;
121     }
122 
123 
124     /**
125      * Encode the EncryptedData message to a PDU.
126      * 
127      * @param buffer The buffer where to put the PDU. It should have been allocated
128      * before, with the right size.
129      * @return The constructed PDU.
130      */
131     @Override
132     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
133     {
134         if ( buffer == null )
135         {
136             throw new EncoderException( I18n.err( I18n.ERR_148 ) );
137         }
138 
139         try
140         {
141             // The AuthorizationData SEQ OF Tag
142             buffer.put( UniversalTag.SEQUENCE.getValue() );
143             buffer.put( TLV.getBytes( authorizationDataSeqSeqLen ) );
144 
145             int i = 0;
146 
147             for ( AuthorizationDataEntry ad : authorizationData )
148             {
149                 buffer.put( UniversalTag.SEQUENCE.getValue() );
150                 buffer.put( TLV.getBytes( authorizationDataSeqLen[i] ) );
151 
152                 // the adType
153                 buffer.put( ( byte ) KerberosConstants.AUTHORIZATION_DATA_ADTYPE_TAG );
154                 buffer.put( TLV.getBytes( adTypeTagLen[i] ) );
155                 BerValue.encode( buffer, ad.getAdType().getValue() );
156 
157                 // the adData
158                 buffer.put( ( byte ) KerberosConstants.AUTHORIZATION_DATA_ADDATA_TAG );
159                 buffer.put( TLV.getBytes( adDataTagLen[i] ) );
160                 BerValue.encode( buffer, ad.getAdDataRef() );
161 
162                 i++;
163             }
164         }
165         catch ( BufferOverflowException boe )
166         {
167             LOG.error( I18n.err( I18n.ERR_139, 1 + TLV.getNbBytes( authorizationDataSeqSeqLen )
168                 + authorizationDataSeqSeqLen, buffer.capacity() ) );
169             throw new EncoderException( I18n.err( I18n.ERR_138 ), boe );
170         }
171 
172         if ( IS_DEBUG )
173         {
174             LOG.debug( "AuthorizationData encoding : {}", Strings.dumpBytes( buffer.array() ) );
175             LOG.debug( "AuthorizationData initial value : {}", this );
176         }
177 
178         return buffer;
179     }
180 
181 
182     /**
183      * @return the currentAD type
184      */
185     public AuthorizationType getCurrentAdType()
186     {
187         return currentAD.getAdType();
188     }
189 
190 
191     /**
192      * Set the current AD type
193      */
194     public void setCurrentAdType( AuthorizationType adType )
195     {
196         currentAD.setAdType( adType );
197     }
198 
199 
200     /**
201      * @return the currentAD data
202      */
203     public byte[] getCurrentAdData()
204     {
205         return currentAD.getAdData();
206     }
207 
208 
209     /**
210      * Set the current AD data
211      */
212     public void setCurrentAdData( byte[] adData )
213     {
214         currentAD.setAdData( adData );
215     }
216 
217 
218     /**
219      * @return the currentAD
220      */
221     public AuthorizationDataEntry getCurrentAD()
222     {
223         return currentAD;
224     }
225 
226 
227     /**
228      * Create a new currentAD
229      */
230     public void createNewAD()
231     {
232         currentAD = new AuthorizationDataEntry();
233         authorizationData.add( currentAD );
234     }
235 
236 
237     /**
238      * Add a new AuthorizationDataEntry
239      */
240     public void addEntry( AuthorizationDataEntry entry )
241     {
242         authorizationData.add( entry );
243     }
244 
245 
246     /**
247      * @return the authorizationData
248      */
249     public List<AuthorizationDataEntry> getAuthorizationData()
250     {
251         return authorizationData;
252     }
253 
254 
255     /**
256      * {@inheritDoc}
257      */
258     @Override
259     public int hashCode()
260     {
261         final int prime = 31;
262         int result = 1;
263         result = prime * result + ( ( authorizationData == null ) ? 0 : authorizationData.hashCode() );
264         result = prime * result + ( ( currentAD == null ) ? 0 : currentAD.hashCode() );
265         return result;
266     }
267 
268 
269     /**
270      * {@inheritDoc}
271      */
272     @Override
273     public boolean equals( Object obj )
274     {
275         if ( this == obj )
276         {
277             return true;
278         }
279 
280         if ( !( obj instanceof AuthorizationData ) )
281         {
282             return false;
283         }
284 
285         AuthorizationData/../../org/apache/directory/shared/kerberos/components/AuthorizationData.html#AuthorizationData">AuthorizationData other = ( AuthorizationData ) obj;
286 
287         if ( authorizationData == null )
288         {
289             if ( other.authorizationData != null )
290             {
291                 return false;
292             }
293         }
294         else if ( !authorizationData.equals( other.authorizationData ) )
295         {
296             return false;
297         }
298 
299         if ( currentAD == null )
300         {
301             if ( other.currentAD != null )
302             {
303                 return false;
304             }
305         }
306         else if ( !currentAD.equals( other.currentAD ) )
307         {
308             return false;
309         }
310 
311         return true;
312     }
313 
314 
315     /**
316      * @see Object#toString()
317      */
318     public String toString( String tabs )
319     {
320         StringBuilder sb = new StringBuilder();
321 
322         sb.append( tabs ).append( "AuthorizationData : \n" );
323 
324         for ( AuthorizationDataEntry ad : authorizationData )
325         {
326             sb.append( ad.toString( tabs + "    " ) );
327         }
328 
329         return sb.toString();
330     }
331 
332 
333     /**
334      * @see Object#toString()
335      */
336     public String toString()
337     {
338         return toString( "" );
339     }
340 }