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 */ 020package org.apache.directory.shared.kerberos.components; 021 022 023import java.nio.BufferOverflowException; 024import java.nio.ByteBuffer; 025 026import org.apache.directory.api.asn1.Asn1Object; 027import org.apache.directory.api.asn1.EncoderException; 028import org.apache.directory.api.asn1.ber.tlv.TLV; 029import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 030import org.apache.directory.api.util.Strings; 031import org.apache.directory.server.i18n.I18n; 032import org.apache.directory.shared.kerberos.KerberosConstants; 033import org.slf4j.Logger; 034import org.slf4j.LoggerFactory; 035 036 037/** 038 * The AdKdcIssued structure is used to store a AD-KDCIssued associated to a type. 039 * 040 * The ASN.1 grammar is : 041 * <pre> 042 * AD-KDCIssued ::= SEQUENCE { 043 * ad-checksum [0] Checksum, 044 * i-realm [1] Realm OPTIONAL, 045 * i-sname [2] PrincipalName OPTIONAL, 046 * elements [3] AuthorizationData 047 * } 048 * </pre> 049 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 050 */ 051public class AdKdcIssued implements Asn1Object 052{ 053 /** The logger */ 054 private static final Logger LOG = LoggerFactory.getLogger( AdKdcIssued.class ); 055 056 /** Speedup for logs */ 057 private static final boolean IS_DEBUG = LOG.isDebugEnabled(); 058 059 /** The checksum */ 060 private Checksum adChecksum; 061 062 /** The realm */ 063 private String irealm; 064 065 /** The PrincipalName */ 066 private PrincipalName isname; 067 068 /** The AuthorizationData */ 069 private AuthorizationData elements; 070 071 // Storage for computed lengths 072 private int adCheksumTagLength; 073 private int irealmTagLength; 074 private byte[] irealmBytes; 075 private int isnameTagLength; 076 private int elementsTagLength; 077 private int adKdcIssuedSeqLength; 078 079 080 /** 081 * Creates a new instance of AdKdcIssued 082 */ 083 public AdKdcIssued() 084 { 085 } 086 087 088 /** 089 * @return the elements 090 */ 091 public AuthorizationData getElements() 092 { 093 return elements; 094 } 095 096 097 /** 098 * @param elements the elements to set 099 */ 100 public void setElements( AuthorizationData elements ) 101 { 102 this.elements = elements; 103 } 104 105 106 /** 107 * @return the adChecksum 108 */ 109 public Checksum getAdChecksum() 110 { 111 return adChecksum; 112 } 113 114 115 /** 116 * @param adChecksum the adChecksum to set 117 */ 118 public void setAdChecksum( Checksum adChecksum ) 119 { 120 this.adChecksum = adChecksum; 121 } 122 123 124 /** 125 * @return the irealm 126 */ 127 public String getIRealm() 128 { 129 return irealm; 130 } 131 132 133 /** 134 * @param irealm the irealm to set 135 */ 136 public void setIRealm( String irealm ) 137 { 138 this.irealm = irealm; 139 } 140 141 142 /** 143 * @return the isname 144 */ 145 public PrincipalName getISName() 146 { 147 return isname; 148 } 149 150 151 /** 152 * @param isname the isname to set 153 */ 154 public void setISName( PrincipalName isname ) 155 { 156 this.isname = isname; 157 } 158 159 160 /** 161 * Compute the AD-KDCIssued length 162 * <pre> 163 * 0x30 L1 AD-KDCIssued sequence 164 * | 165 * +--> 0xA1 L2 ad-checksum tag 166 * | | 167 * | +--> 0x30 L2-1 ad-checksum value ( Checksum ) 168 * | 169 * +--> 0xA2 L3 i-realm tag 170 * | | 171 * | +--> 0x1B L3-1 i-realm value ( KerberosString ) 172 * | 173 * +--> 0xA3 L4 i-sname tag 174 * | | 175 * | +--> 0x30 L4-1 i-sname value ( PrincipalName ) 176 * | 177 * +--> 0xA4 L5 elements tag 178 * | 179 * +--> 0x30 L5-1 elements (AuthorizationData) 180 * </pre> 181 */ 182 @Override 183 public int computeLength() 184 { 185 // Compute the ad-cheksum count length 186 adCheksumTagLength = adChecksum.computeLength(); 187 adKdcIssuedSeqLength = 1 + TLV.getNbBytes( adCheksumTagLength ) + adCheksumTagLength; 188 189 // Compute the i-realm length, if any 190 if ( irealm != null ) 191 { 192 irealmBytes = Strings.getBytesUtf8( irealm ); 193 irealmTagLength = 1 + TLV.getNbBytes( irealmBytes.length ) + irealmBytes.length; 194 adKdcIssuedSeqLength += 1 + TLV.getNbBytes( irealmTagLength ) + irealmTagLength; 195 } 196 197 // Compute the i-sname length, if any 198 if ( isname != null ) 199 { 200 isnameTagLength = isname.computeLength(); 201 adKdcIssuedSeqLength += 1 + TLV.getNbBytes( isnameTagLength ) + isnameTagLength; 202 } 203 204 // Compute the elements count length 205 elementsTagLength = elements.computeLength(); 206 adKdcIssuedSeqLength += 1 + TLV.getNbBytes( elementsTagLength ) + elementsTagLength; 207 208 // Compute the whole sequence length 209 return 1 + TLV.getNbBytes( adKdcIssuedSeqLength ) + adKdcIssuedSeqLength; 210 } 211 212 213 /** 214 * Encode the AD-KDCIssued message to a PDU. 215 * 216 * @param buffer The buffer where to put the PDU. It should have been allocated 217 * before, with the right size. 218 * @return The constructed PDU. 219 */ 220 @Override 221 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 222 { 223 if ( buffer == null ) 224 { 225 throw new EncoderException( I18n.err( I18n.ERR_148 ) ); 226 } 227 228 try 229 { 230 // The AD-KDCIssued SEQ Tag 231 buffer.put( UniversalTag.SEQUENCE.getValue() ); 232 buffer.put( TLV.getBytes( adKdcIssuedSeqLength ) ); 233 234 // the ad-checksum 235 buffer.put( ( byte ) KerberosConstants.AD_KDC_ISSUED_AD_CHECKSUM_TAG ); 236 buffer.put( ( byte ) adCheksumTagLength ); 237 adChecksum.encode( buffer ); 238 239 // the i-realm, if any 240 if ( irealm != null ) 241 { 242 buffer.put( ( byte ) KerberosConstants.AD_KDC_ISSUED_I_REALM_TAG ); 243 buffer.put( ( byte ) irealmTagLength ); 244 buffer.put( UniversalTag.GENERAL_STRING.getValue() ); 245 buffer.put( ( byte ) irealmBytes.length ); 246 buffer.put( irealmBytes ); 247 } 248 249 // the i-sname, if any 250 if ( isname != null ) 251 { 252 buffer.put( ( byte ) KerberosConstants.AD_KDC_ISSUED_I_SNAME_TAG ); 253 buffer.put( ( byte ) isnameTagLength ); 254 isname.encode( buffer ); 255 } 256 257 // the elements 258 buffer.put( ( byte ) KerberosConstants.AD_KDC_ISSUED_ELEMENTS_TAG ); 259 buffer.put( ( byte ) elementsTagLength ); 260 elements.encode( buffer ); 261 } 262 catch ( BufferOverflowException boe ) 263 { 264 LOG.error( I18n.err( I18n.ERR_139, 1 + TLV.getNbBytes( adKdcIssuedSeqLength ) 265 + adKdcIssuedSeqLength, buffer.capacity() ) ); 266 throw new EncoderException( I18n.err( I18n.ERR_138 ), boe ); 267 } 268 269 if ( IS_DEBUG ) 270 { 271 LOG.debug( "AD-KDCIssued encoding : {}", Strings.dumpBytes( buffer.array() ) ); 272 LOG.debug( "AD-KDCIssued initial value : {}", this ); 273 } 274 275 return buffer; 276 } 277 278 279 /** 280 * @see Object#toString() 281 */ 282 public String toString() 283 { 284 return toString( "" ); 285 } 286 287 288 /** 289 * @see Object#toString() 290 */ 291 public String toString( String tabs ) 292 { 293 StringBuilder sb = new StringBuilder(); 294 295 sb.append( tabs ).append( "AD-KDCIssued : {\n" ); 296 sb.append( tabs ).append( " ad-cheksum: " ).append( adChecksum.toString( tabs + " " ) ).append( '\n' ); 297 298 if ( irealm != null ) 299 { 300 sb.append( tabs ).append( " i-realm: " ).append( irealm ).append( '\n' ); 301 } 302 303 if ( isname != null ) 304 { 305 sb.append( tabs ).append( " i-sname: " ).append( isname.toString() ).append( '\n' ); 306 } 307 308 sb.append( tabs + " elements:" ).append( elements.toString( tabs + " " ) ).append( '\n' ); 309 sb.append( tabs + "}\n" ); 310 311 return sb.toString(); 312 } 313}