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; 026import java.util.ArrayList; 027import java.util.List; 028 029import org.apache.directory.api.asn1.Asn1Object; 030import org.apache.directory.api.asn1.EncoderException; 031import org.apache.directory.api.asn1.ber.tlv.BerValue; 032import org.apache.directory.api.asn1.ber.tlv.TLV; 033import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 034import org.apache.directory.api.util.Strings; 035import org.apache.directory.server.i18n.I18n; 036import org.apache.directory.shared.kerberos.KerberosConstants; 037import org.apache.directory.shared.kerberos.codec.types.AuthorizationType; 038import org.slf4j.Logger; 039import org.slf4j.LoggerFactory; 040 041 042/** 043 * A structure to hold the authorization data. 044 * 045 * <pre> 046 * AuthorizationData ::= SEQUENCE OF SEQUENCE { 047 * ad-type [0] Int32, 048 * ad-data [1] OCTET STRING 049 * } 050 *</pre> 051 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 052 */ 053public class AuthorizationData implements Asn1Object 054{ 055 /** The list of AuthorizationData elements */ 056 private List<AuthorizationDataEntry> authorizationData = new ArrayList<>(); 057 058 /** The current AD being processed */ 059 private AuthorizationDataEntry currentAD; 060 061 /** The logger */ 062 private static final Logger LOG = LoggerFactory.getLogger( EncryptedData.class ); 063 064 /** Speedup for logs */ 065 private static final boolean IS_DEBUG = LOG.isDebugEnabled(); 066 067 // Storage for computed lengths 068 private int adTypeTagLen[]; 069 private int adDataTagLen[]; 070 private int authorizationDataSeqLen[]; 071 private int authorizationDataSeqSeqLen; 072 073 074 /** 075 * Creates a new set of AuthorizationData 076 */ 077 public AuthorizationData() 078 { 079 } 080 081 082 /** 083 * Compute the AuthorizationData length 084 * <pre> 085 * 0x30 L1 AuthorizationData sequence 086 * | 087 * +-- 0x30 L2 The AD sequence 088 * | 089 * +--> 0xA0 L3 adType tag 090 * | | 091 * | +--> 0x02 L3-1 adType (int) 092 * | 093 * +--> 0xA1 L4 adData tag 094 * | 095 * +--> 0x04 L4-1 adData (OCTET STRING) 096 * </pre> 097 */ 098 @Override 099 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 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}