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; 026 027import org.apache.directory.api.asn1.Asn1Object; 028import org.apache.directory.api.asn1.EncoderException; 029import org.apache.directory.api.asn1.ber.tlv.BerValue; 030import org.apache.directory.api.asn1.ber.tlv.TLV; 031import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 032import org.apache.directory.api.util.Strings; 033import org.apache.directory.server.i18n.I18n; 034import org.apache.directory.shared.kerberos.KerberosConstants; 035import org.apache.directory.shared.kerberos.KerberosTime; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039 040/** 041 * The EncKrbPrivPart structure is used to store a EncKrbPrivPart associated to a type. 042 * 043 * The ASN.1 grammar is : 044 * <pre> 045 * EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE { 046 * user-data [0] OCTET STRING, 047 * timestamp [1] KerberosTime OPTIONAL, 048 * usec [2] Microseconds OPTIONAL, 049 * seq-number [3] UInt32 OPTIONAL, 050 * s-address [4] HostAddress -- sender's addr --, 051 * r-address [5] HostAddress OPTIONAL -- recip's addr 052 * } 053 * </pre> 054 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 055 */ 056//NOTE: this ASN.1 structure is quite identical to KrbSafeBody 057public class EncKrbPrivPart implements Asn1Object 058{ 059 /** The logger */ 060 private static final Logger log = LoggerFactory.getLogger( EncKrbPrivPart.class ); 061 062 /** Speedup for logs */ 063 private static final boolean IS_DEBUG = log.isDebugEnabled(); 064 065 /** the user data */ 066 private byte[] userData; 067 068 /** the current time of the sender */ 069 private KerberosTime timestamp; 070 071 /** the microsecond part of the timestamp */ 072 private Integer usec; 073 074 /** the sequence number */ 075 private Integer seqNumber; 076 077 /** the sender's address */ 078 private HostAddress senderAddress; 079 080 /** the recipient's address */ 081 private HostAddress recipientAddress; 082 083 // Storage for computed lengths 084 private int userDataLen; 085 private int timestampLen; 086 private int usecLen; 087 private int seqNumberLen; 088 private int senderAddressLen; 089 private int recipientAddressLen; 090 private int encKrbPrivPartSeqLen; 091 private int encKrbPrivPartLen; 092 093 094 /** 095 * @return the userData 096 */ 097 public byte[] getUserData() 098 { 099 return userData; 100 } 101 102 103 /** 104 * @param userData the userData to set 105 */ 106 public void setUserData( byte[] userData ) 107 { 108 this.userData = userData; 109 } 110 111 112 /** 113 * @return the timestamp 114 */ 115 public KerberosTime getTimestamp() 116 { 117 return timestamp; 118 } 119 120 121 /** 122 * @param timestamp the timestamp to set 123 */ 124 public void setTimestamp( KerberosTime timestamp ) 125 { 126 this.timestamp = timestamp; 127 } 128 129 130 /** 131 * @return the usec 132 */ 133 public int getUsec() 134 { 135 if ( usec == null ) 136 { 137 return 0; 138 } 139 140 return usec; 141 } 142 143 144 /** 145 * @param usec the usec to set 146 */ 147 public void setUsec( int usec ) 148 { 149 this.usec = usec; 150 } 151 152 153 /** 154 * @return the seqNumber 155 */ 156 public int getSeqNumber() 157 { 158 if ( seqNumber == null ) 159 { 160 return 0; 161 } 162 163 return seqNumber; 164 } 165 166 167 /** 168 * @param seqNumber the seqNumber to set 169 */ 170 public void setSeqNumber( int seqNumber ) 171 { 172 this.seqNumber = seqNumber; 173 } 174 175 176 /** 177 * @return the senderAddress 178 */ 179 public HostAddress getSenderAddress() 180 { 181 return senderAddress; 182 } 183 184 185 /** 186 * @param senderAddress the senderAddress to set 187 */ 188 public void setSenderAddress( HostAddress senderAddress ) 189 { 190 this.senderAddress = senderAddress; 191 } 192 193 194 /** 195 * @return the recipientAddress 196 */ 197 public HostAddress getRecipientAddress() 198 { 199 return recipientAddress; 200 } 201 202 203 /** 204 * @param recipientAddress the recipientAddress to set 205 */ 206 public void setRecipientAddress( HostAddress recipientAddress ) 207 { 208 this.recipientAddress = recipientAddress; 209 } 210 211 212 /** 213 * Compute the EncKrbPrivPart length: 214 * 215 * <pre> 216 * 0x7C L0 EncKrbPrivPart 217 * | 218 * | 219 * 0x30 L1 EncKrbPrivPart SEQ 220 * | 221 * +--> 0xA0 L2 user-data tag 222 * | | 223 * | +--> 0x04 L2-1 user-data (Octet String) 224 * | 225 * +--> 0xA1 0x11 timestamp tag 226 * | | 227 * | +--> 0x18 0x0F timestamp (KerberosTime) 228 * | 229 * +--> 0xA2 L3 usec tag 230 * | | 231 * | +--> 0x02 L3-1 usec (Microseconds) 232 * | 233 * +--> 0xA3 L4 seq-number tag 234 * | | 235 * | +--> 0x02 L4-1 seqnumber (UInt32) 236 * | 237 * +--> 0xA4 L5 s-address tag 238 * | | 239 * | +--> 0x30 L5-1 s-address (HostAddress) 240 * | 241 * +--> 0xA5 L6 r-address tag 242 * | 243 * +--> 0x30 L6-1 r-address (HostAddress) 244 * </pre> 245 */ 246 @Override 247 public int computeLength() 248 { 249 userDataLen = 1 + TLV.getNbBytes( userData.length ) + userData.length; 250 encKrbPrivPartSeqLen = 1 + TLV.getNbBytes( userDataLen ) + userDataLen; 251 252 senderAddressLen = senderAddress.computeLength(); 253 encKrbPrivPartSeqLen += 1 + TLV.getNbBytes( senderAddressLen ) + senderAddressLen; 254 255 if ( timestamp != null ) 256 { 257 timestampLen = timestamp.getBytes().length; 258 timestampLen = 1 + TLV.getNbBytes( timestampLen ) + timestampLen; 259 encKrbPrivPartSeqLen += 1 + TLV.getNbBytes( timestampLen ) + timestampLen; 260 } 261 262 if ( usec != null ) 263 { 264 usecLen = BerValue.getNbBytes( usec ); 265 usecLen = 1 + TLV.getNbBytes( usecLen ) + usecLen; 266 encKrbPrivPartSeqLen += 1 + TLV.getNbBytes( usecLen ) + usecLen; 267 } 268 269 if ( seqNumber != null ) 270 { 271 seqNumberLen = BerValue.getNbBytes( seqNumber ); 272 seqNumberLen = 1 + TLV.getNbBytes( seqNumberLen ) + seqNumberLen; 273 encKrbPrivPartSeqLen += 1 + TLV.getNbBytes( seqNumberLen ) + seqNumberLen; 274 } 275 276 if ( recipientAddress != null ) 277 { 278 recipientAddressLen = recipientAddress.computeLength(); 279 encKrbPrivPartSeqLen += 1 + TLV.getNbBytes( recipientAddressLen ) + recipientAddressLen; 280 } 281 282 encKrbPrivPartLen = 1 + TLV.getNbBytes( encKrbPrivPartSeqLen ) + encKrbPrivPartSeqLen; 283 284 return 1 + TLV.getNbBytes( encKrbPrivPartLen ) + encKrbPrivPartLen; 285 } 286 287 288 /** 289 * {@inheritDoc} 290 */ 291 @Override 292 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 293 { 294 if ( buffer == null ) 295 { 296 throw new EncoderException( I18n.err( I18n.ERR_148 ) ); 297 } 298 299 try 300 { 301 buffer.put( ( byte ) KerberosConstants.ENC_KRB_PRIV_PART_TAG ); 302 buffer.put( TLV.getBytes( encKrbPrivPartLen ) ); 303 304 buffer.put( UniversalTag.SEQUENCE.getValue() ); 305 buffer.put( TLV.getBytes( encKrbPrivPartSeqLen ) ); 306 307 // user-data 308 buffer.put( ( byte ) KerberosConstants.KRB_SAFE_BODY_USER_DATA_TAG ); 309 buffer.put( TLV.getBytes( userDataLen ) ); 310 BerValue.encode( buffer, userData ); 311 312 if ( timestamp != null ) 313 { 314 // timestamp tag 315 buffer.put( ( byte ) KerberosConstants.KRB_SAFE_BODY_TIMESTAMP_TAG ); 316 buffer.put( TLV.getBytes( timestampLen ) ); 317 318 // timestamp value 319 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() ); 320 buffer.put( ( byte ) 0x0F ); 321 buffer.put( timestamp.getBytes() ); 322 } 323 324 if ( usec != null ) 325 { 326 // usec 327 buffer.put( ( byte ) KerberosConstants.KRB_SAFE_BODY_USEC_TAG ); 328 buffer.put( TLV.getBytes( usecLen ) ); 329 BerValue.encode( buffer, usec ); 330 } 331 332 if ( seqNumber != null ) 333 { 334 // seq-number 335 buffer.put( ( byte ) KerberosConstants.KRB_SAFE_BODY_SEQ_NUMBER_TAG ); 336 buffer.put( TLV.getBytes( seqNumberLen ) ); 337 BerValue.encode( buffer, seqNumber ); 338 } 339 340 // s-address 341 buffer.put( ( byte ) KerberosConstants.KRB_SAFE_BODY_SENDER_ADDRESS_TAG ); 342 buffer.put( TLV.getBytes( senderAddressLen ) ); 343 senderAddress.encode( buffer ); 344 345 if ( recipientAddress != null ) 346 { 347 // s-address 348 buffer.put( ( byte ) KerberosConstants.KRB_SAFE_BODY_RECIPIENT_ADDRESS_TAG ); 349 buffer.put( TLV.getBytes( recipientAddressLen ) ); 350 recipientAddress.encode( buffer ); 351 } 352 } 353 catch ( BufferOverflowException boe ) 354 { 355 log.error( I18n.err( I18n.ERR_735_CANNOT_ENCODE_KRBSAFEBODY, 1 + TLV.getNbBytes( encKrbPrivPartLen ) 356 + encKrbPrivPartLen, buffer.capacity() ) ); 357 throw new EncoderException( I18n.err( I18n.ERR_138 ), boe ); 358 } 359 360 if ( IS_DEBUG ) 361 { 362 log.debug( "EncKrbPrivPart encoding : {}", Strings.dumpBytes( buffer.array() ) ); 363 log.debug( "EncKrbPrivPart initial value : {}", this ); 364 } 365 366 return buffer; 367 } 368 369 370 /** 371 * @see Object#toString() 372 */ 373 public String toString() 374 { 375 StringBuilder sb = new StringBuilder(); 376 377 sb.append( "EncKrbPrivPart : {\n" ); 378 sb.append( " user-data: " ).append( Strings.dumpBytes( userData ) ).append( '\n' ); 379 380 if ( timestamp != null ) 381 { 382 sb.append( " timestamp: " ).append( timestamp.getDate() ).append( '\n' ); 383 } 384 385 if ( usec != null ) 386 { 387 sb.append( " usec: " ).append( usec ).append( '\n' ); 388 } 389 390 if ( seqNumber != null ) 391 { 392 sb.append( " seq-number: " ).append( seqNumber ).append( '\n' ); 393 } 394 395 sb.append( " s-address: " ).append( senderAddress ).append( '\n' ); 396 397 if ( recipientAddress != null ) 398 { 399 sb.append( " r-address: " ).append( recipientAddress ).append( '\n' ); 400 } 401 402 sb.append( "}\n" ); 403 404 return sb.toString(); 405 } 406}