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 package org.apache.directory.server.kerberos.shared.messages.value; 021 022 023 import java.nio.BufferOverflowException; 024 import java.nio.ByteBuffer; 025 026 import org.apache.directory.server.i18n.I18n; 027 import org.apache.directory.server.kerberos.shared.messages.value.types.AuthorizationType; 028 import org.apache.directory.shared.asn1.AbstractAsn1Object; 029 import org.apache.directory.shared.asn1.ber.tlv.TLV; 030 import org.apache.directory.shared.asn1.ber.tlv.UniversalTag; 031 import org.apache.directory.shared.asn1.ber.tlv.Value; 032 import org.apache.directory.shared.asn1.codec.EncoderException; 033 import org.apache.directory.shared.ldap.util.StringTools; 034 import org.slf4j.Logger; 035 import org.slf4j.LoggerFactory; 036 037 038 /** 039 * A single AuthorizationData 040 * 041 * The ASN.1 grammar is : 042 * -- NOTE: AuthorizationData is always used as an OPTIONAL field and 043 * -- should not be empty. 044 * AuthorizationDataEntry ::= SEQUENCE { 045 * ad-type [0] Int32, 046 * ad-data [1] OCTET STRING 047 * } 048 * 049 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 050 * @version $Rev: 902575 $, $Date: 2010-01-24 15:38:06 +0100 (Sun, 24 Jan 2010) $ 051 */ 052 public class AuthorizationDataEntry extends AbstractAsn1Object 053 { 054 /** The logger */ 055 private static final Logger log = LoggerFactory.getLogger( AuthorizationDataEntry.class ); 056 057 /** Speedup for logs */ 058 private static final boolean IS_DEBUG = log.isDebugEnabled(); 059 060 /** The Authorization type. One of : 061 * DER encoding of AD-IF-RELEVANT 1 062 * DER encoding of AD-KDCIssued 4 063 * DER encoding of AD-AND-OR 5 064 * DER encoding of AD-MANDATORY-FOR-KDC 8 065 **/ 066 private AuthorizationType adType; 067 068 /** The data, encrypted */ 069 private byte[] adData; 070 071 // Storage for computed lengths 072 private transient int adTypeLength; 073 private transient int adDataLength; 074 private transient int authorizationDataEntryLength; 075 076 077 /** 078 * Creates a new instance of AuthorizationDataEntry. 079 */ 080 public AuthorizationDataEntry() 081 { 082 } 083 084 085 /** 086 * Creates a new instance of AuthorizationDataEntry. 087 * 088 * @param adType The authorizationType 089 * @param adData The authorization data 090 */ 091 public AuthorizationDataEntry( AuthorizationType adType, byte[] adData ) 092 { 093 this.adType = adType; 094 this.adData = adData; 095 } 096 097 098 /** 099 * Returns the raw bytes of the authorization data. 100 * 101 * @return The raw bytes of the authorization data. 102 */ 103 public byte[] getAdData() 104 { 105 return adData; 106 } 107 108 109 /** 110 * Set the authorization data 111 * 112 * @param adData The data 113 */ 114 public void setAdData( byte[] adData ) 115 { 116 this.adData = adData; 117 } 118 119 120 /** 121 * Returns the {@link AuthorizationType}. 122 * 123 * @return The {@link AuthorizationType}. 124 */ 125 public AuthorizationType getAdType() 126 { 127 return adType; 128 } 129 130 131 /** 132 * Set the authorization type 133 * @param adType The authorization type 134 */ 135 public void setAdType( int adType ) 136 { 137 this.adType = AuthorizationType.getTypeByOrdinal( adType ); 138 } 139 140 141 /** 142 * Set the authorization type 143 * @param adType The authorization type 144 */ 145 public void setAdType( AuthorizationType adType ) 146 { 147 this.adType = adType; 148 } 149 150 151 /** 152 * Compute the AuthorizationDataEntry length 153 * 154 * AuthorizationDataEntry : 155 * 156 * 0x30 L1 AuthorizationDataEntry 157 * | 158 * +--> 0xA0 L2 adType tag 159 * | | 160 * | +--> 0x02 L2-1 adType (int) 161 * | 162 * +--> 0xA1 L3 adData tag 163 * | 164 * +--> 0x04 L3-1 adData (OCTET STRING) 165 * 166 * where L1 = L2 + lenght(0xA0) + length(L2) + 167 * L3 + lenght(0xA1) + length(L3) 168 * and 169 * L2 = L2-1 + length(0x02) + length( L2-1) 170 * L3 = L3-1 + length(0x04) + length( L3-1) 171 */ 172 public int computeLength() 173 { 174 // Compute the adType. The Length will always be contained in 1 byte 175 adTypeLength = 1 + 1 + Value.getNbBytes( adType.getOrdinal() ); 176 authorizationDataEntryLength = 1 + TLV.getNbBytes( adTypeLength ) + adTypeLength; 177 178 // Compute the keyValue 179 if ( adData == null ) 180 { 181 adDataLength = 1 + 1; 182 } 183 else 184 { 185 adDataLength = 1 + TLV.getNbBytes( adData.length ) + adData.length; 186 } 187 188 authorizationDataEntryLength += 1 + TLV.getNbBytes( adDataLength ) + adDataLength; 189 190 // Compute the whole sequence length 191 int authorizationDataEntrySeqLength = 1 + Value.getNbBytes( authorizationDataEntryLength ) 192 + authorizationDataEntryLength; 193 194 return authorizationDataEntrySeqLength; 195 196 } 197 198 199 /** 200 * Encode the AuthorizationDataEntry message to a PDU. 201 * 202 * AuthorizationDataEntry : 203 * 204 * 0x30 LL 205 * 0xA0 LL 206 * 0x02 0x01 adType 207 * 0xA1 LL 208 * 0x04 LL adData 209 * 210 * @param buffer The buffer where to put the PDU. It should have been allocated 211 * before, with the right size. 212 * @return The constructed PDU. 213 */ 214 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 215 { 216 if ( buffer == null ) 217 { 218 throw new EncoderException( I18n.err( I18n.ERR_148 ) ); 219 } 220 221 try 222 { 223 // The AuthorizationDataEntry SEQ Tag 224 buffer.put( UniversalTag.SEQUENCE_TAG ); 225 buffer.put( TLV.getBytes( authorizationDataEntryLength ) ); 226 227 // The adType, first the tag, then the value 228 buffer.put( ( byte ) 0xA0 ); 229 buffer.put( TLV.getBytes( adTypeLength ) ); 230 Value.encode( buffer, adType.getOrdinal() ); 231 232 // The adData, first the tag, then the value 233 buffer.put( ( byte ) 0xA1 ); 234 buffer.put( TLV.getBytes( adDataLength ) ); 235 Value.encode( buffer, adData ); 236 } 237 catch ( BufferOverflowException boe ) 238 { 239 log 240 .error( I18n.err( I18n.ERR_622, 1 + TLV.getNbBytes( authorizationDataEntryLength ) + authorizationDataEntryLength, 241 buffer.capacity() ) ); 242 throw new EncoderException( I18n.err( I18n.ERR_138 ) ); 243 } 244 245 if ( IS_DEBUG ) 246 { 247 log.debug( "AuthorizationDataEntry encoding : {}", StringTools.dumpBytes( buffer.array() ) ); 248 log.debug( "AuthorizationDataEntry initial value : {}", toString() ); 249 } 250 251 return buffer; 252 } 253 254 255 /** 256 * @see Object#toString() 257 */ 258 public String toString() 259 { 260 return toString( " " ); 261 } 262 263 264 /** 265 * @see Object#toString() 266 */ 267 public String toString( String tabs ) 268 { 269 StringBuilder sb = new StringBuilder(); 270 271 sb.append( tabs ).append( "AuthorizationDataEntry : {\n" ); 272 sb.append( tabs ).append( " ad-type: " ).append( adType ).append( '\n' ); 273 274 sb.append( tabs ).append( " ad-data: " ).append( StringTools.dumpBytes( adData ) ) 275 .append( "\n" + tabs + "}" ); 276 277 return sb.toString(); 278 } 279 }