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.server.kerberos.shared.messages.value;
21  
22  
23  import java.nio.BufferOverflowException;
24  import java.nio.ByteBuffer;
25  
26  import org.apache.directory.server.kerberos.shared.messages.value.types.TransitedEncodingType;
27  import org.apache.directory.shared.asn1.AbstractAsn1Object;
28  import org.apache.directory.shared.asn1.ber.tlv.TLV;
29  import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
30  import org.apache.directory.shared.asn1.ber.tlv.Value;
31  import org.apache.directory.shared.asn1.codec.EncoderException;
32  import org.apache.directory.shared.ldap.util.StringTools;
33  import org.slf4j.Logger;
34  import org.slf4j.LoggerFactory;
35  
36  
37  /**
38   * The TransitedEncoding structure.
39   * 
40   * The ASN.1 grammar is :
41   * 
42   * -- encoded Transited field
43   * TransitedEncoding       ::= SEQUENCE {
44   *         tr-type         [0] Int32 -- must be registered --,
45   *         contents        [1] OCTET STRING
46   * }
47   * 
48   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
49   * @version $Rev: 642496 $, $Date: 2008-03-29 04:09:22 +0100 (Sa, 29 Mär 2008) $
50   */
51  public class TransitedEncoding extends AbstractAsn1Object
52  {
53      /** The logger */
54      private static final Logger log = LoggerFactory.getLogger( TransitedEncoding.class );
55  
56      /** Speedup for logs */
57      private static final boolean IS_DEBUG = log.isDebugEnabled();
58  
59      /** The transited type. One of :
60       * NULL
61       * DOMAIN_X500_COMPRESS
62       */
63      private TransitedEncodingType trType;
64  
65      /** The transited data */
66      private byte[] contents;
67  
68      // Storage for computed lengths
69      private transient int trTypeLength;
70      private transient int contentsLength;
71      private transient int transitedEncodingLength;
72  
73  
74      /**
75       * Creates a new instance of TransitedEncoding.
76       */
77      public TransitedEncoding()
78      {
79          trType = TransitedEncodingType.NULL;
80          contents = new byte[0];
81      }
82  
83  
84      /**
85       * Creates a new instance of TransitedEncoding.
86       *
87       * @param trType
88       * @param contents
89       */
90      public TransitedEncoding( TransitedEncodingType trType, byte[] contents )
91      {
92          this.trType = trType;
93          this.contents = contents;
94      }
95  
96  
97      /**
98       * Returns the contents.
99       *
100      * @return The contents.
101      */
102     public byte[] getContents()
103     {
104         return contents;
105     }
106     
107     
108     /**
109      * Set the contents
110      * @param contents The contents
111      */
112     public void setContents( byte[] contents )
113     {
114         this.contents = contents;
115     }
116 
117 
118     /**
119      * Returns the {@link TransitedEncodingType}.
120      *
121      * @return The {@link TransitedEncodingType}.
122      */
123     public TransitedEncodingType getTrType()
124     {
125         return trType;
126     }
127     
128     
129     /**
130      * Set the transited encoding type
131      * @param trType The transited encoding type
132      */
133     public void setTrType( TransitedEncodingType trType )
134     {
135         this.trType = trType;
136     }
137 
138 
139     /**
140      * Compute the TransitedEncoding length
141      * 
142      * TransitedEncoding :
143      * 
144      * 0x30 L1 TransitedEncoding
145      *  |
146      *  +--> 0xA0 L2 trType tag
147      *  |     |
148      *  |     +--> 0x02 L2-1 trType (int)
149      *  |
150      *  +--> 0xA1 L3 contents tag
151      *        |
152      *        +--> 0x04 L3-1 contents (OCTET STRING)
153      *        
154      *  where L1 = L2 + lenght(0xA0) + length(L2) +
155      *             L3 + lenght(0xA1) + length(L3) 
156      *  and
157      *  L2 = L2-1 + length(0x02) + length( L2-1) 
158      *  L3 = L3-1 + length(0x04) + length( L3-1) 
159      */
160     public int computeLength()
161     {
162         // Compute the trType. The Length will always be contained in 1 byte
163         trTypeLength = 1 + 1 + Value.getNbBytes( trType.getOrdinal() );
164         transitedEncodingLength = 1 + TLV.getNbBytes( trTypeLength ) + trTypeLength;
165 
166         // Compute the keyValue
167         if ( contents == null )
168         {
169             contentsLength = 1 + 1;
170         }
171         else
172         {
173             contentsLength = 1 + TLV.getNbBytes( contents.length ) + contents.length;
174         }
175 
176         transitedEncodingLength += 1 + TLV.getNbBytes( contentsLength ) + contentsLength;
177 
178         // Compute the whole sequence length
179         int transitedEncodingSeqLength = 1 + Value.getNbBytes( transitedEncodingLength ) + transitedEncodingLength;
180 
181         return transitedEncodingSeqLength;
182 
183     }
184 
185 
186     /**
187      * Encode the TransitedEncoding message to a PDU. 
188      * 
189      * TransitedEncoding :
190      * 
191      * 0x30 LL
192      *   0xA0 LL 
193      *     0x02 0x01 trType
194      *   0xA1 LL 
195      *     0x04 LL adData
196      * 
197      * @param buffer The buffer where to put the PDU. It should have been allocated
198      * before, with the right size.
199      * @return The constructed PDU.
200      */
201     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
202     {
203         if ( buffer == null )
204         {
205             throw new EncoderException( "Cannot put a PDU in a null buffer !" );
206         }
207 
208         try
209         {
210             // The AuthorizationDataEntry SEQ Tag
211             buffer.put( UniversalTag.SEQUENCE_TAG );
212             buffer.put( TLV.getBytes( transitedEncodingLength ) );
213 
214             // The tr-type, first the tag, then the value
215             buffer.put( ( byte ) 0xA0 );
216             buffer.put( TLV.getBytes( trTypeLength ) );
217             Value.encode( buffer, trType.getOrdinal() );
218 
219             // The contents, first the tag, then the value
220             buffer.put( ( byte ) 0xA1 );
221             buffer.put( TLV.getBytes( contentsLength ) );
222             Value.encode( buffer, contents );
223         }
224         catch ( BufferOverflowException boe )
225         {
226             log.error(
227                 "Cannot encode the TransitedEncoding object, the PDU size is {} when only {} bytes has been allocated",
228                 1 + TLV.getNbBytes( transitedEncodingLength ) + transitedEncodingLength, buffer.capacity() );
229             throw new EncoderException( "The PDU buffer size is too small !" );
230         }
231 
232         if ( IS_DEBUG )
233         {
234             log.debug( "TransitedEncoding encoding : {}", StringTools.dumpBytes( buffer.array() ) );
235             log.debug( "TransitedEncoding initial value : {}", toString() );
236         }
237 
238         return buffer;
239     }
240 
241 
242     /**
243      * @see Object#toString()
244      */
245     public String toString()
246     {
247         StringBuilder sb = new StringBuilder();
248 
249         sb.append( "TransitedEncoding : {\n" );
250         sb.append( "    tr-type: " ).append( trType ).append( '\n' );
251 
252         sb.append( "    contents: " ).append( StringTools.dumpBytes( contents ) ).append( "\n}\n" );
253 
254         return sb.toString();
255     }
256 }