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.apache.directory.shared.kerberos.flags.TicketFlag; 037import org.apache.directory.shared.kerberos.flags.TicketFlags; 038import org.slf4j.Logger; 039import org.slf4j.LoggerFactory; 040 041 042/** 043 * EncTicketPart ::= [APPLICATION 3] SEQUENCE { 044 * flags [0] TicketFlags, 045 * key [1] EncryptionKey, 046 * crealm [2] Realm, 047 * cname [3] PrincipalName, 048 * transited [4] TransitedEncoding, 049 * authtime [5] KerberosTime, 050 * starttime [6] KerberosTime OPTIONAL, 051 * endtime [7] KerberosTime, 052 * renew-till [8] KerberosTime OPTIONAL, 053 * caddr [9] HostAddresses OPTIONAL, 054 * authorization-data [10] AuthorizationData OPTIONAL 055 * } 056 * 057 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 058 */ 059public class EncTicketPart implements Asn1Object 060{ 061 /** The logger */ 062 private static final Logger log = LoggerFactory.getLogger( EncTicketPart.class ); 063 064 /** Speedup for logs */ 065 private static final boolean IS_DEBUG = log.isDebugEnabled(); 066 067 /** the ticket's flags */ 068 private TicketFlags flags = new TicketFlags(); 069 070 /** the encryption key */ 071 private EncryptionKey key; 072 073 /** the client's realm */ 074 private String cRealm; 075 076 /** client's principal */ 077 private PrincipalName cName; 078 079 /** field containing list of transited realm names */ 080 private TransitedEncoding transited; 081 082 /** time of initial authentication */ 083 private KerberosTime authTime; 084 085 /** time after which ticket is valid */ 086 private KerberosTime startTime; 087 088 /** ticket's expiry time */ 089 private KerberosTime endTime; 090 091 /** the maximum endtime that may be included in a renewal */ 092 private KerberosTime renewtill; 093 094 /** the addresses from which this ticket can be used */ 095 private HostAddresses clientAddresses; 096 097 /** the authorization data */ 098 private AuthorizationData authorizationData; 099 100 private int flagsLen; 101 private int keyLen; 102 private int cRealmLen; 103 private byte[] cRealmBytes; 104 private int cNameLen; 105 private int transitedLen; 106 private int authTimeLen; 107 private byte[] authTimeBytes; 108 private int startTimeLen; 109 private byte[] startTimeBytes; 110 private int endTimeLen; 111 private byte[] endTimeBytes; 112 private int renewtillLen; 113 private byte[] renewtillBytes; 114 private int clientAddressesLen; 115 private int authzDataLen; 116 private int encTikcetPartSeqLen; 117 private int encTikcetPartLen; 118 119 120 /** 121 * compute length for EncTicketPart: 122 * <pre> 123 * 0x63 L1 EncTicketPart tag 124 * | 125 * +--> 0x30 L1-2 EncTicketPart seq 126 * | 127 * +--> 0xA0 L2 flags tag 128 * | | 129 * | +--> 0x03 L2-2 flags (BitString) 130 * | 131 * +--> 0xA1 L3 key tag 132 * | | 133 * | +--> 0x30 L3-2 key (EncryptionKey) 134 * | 135 * +--> 0xA2 L4 crealm tag 136 * | | 137 * | +--> 0x1B L4-2 crealm (Realm) 138 * | 139 * +--> 0xA3 L5 cname tag 140 * | | 141 * | +--> 0x30 L5-2 cname (PrincipalName) 142 * | 143 * +--> 0xA4 L6 transited tag 144 * | | 145 * | +--> 0x30 L6-2 transited (TransitedEncoding) 146 * | 147 * +--> 0xA5 0x11 authtime tag 148 * | | 149 * | +--> 0x18 0x0F authtime (KerberosTime) 150 * | 151 * +--> [0xA6 0x11 starttime tag 152 * | | 153 * | +--> 0x18 0x0F starttime (KerberosTime)] 154 * | 155 * +--> 0xA7 0x11 endtime tag 156 * | | 157 * | +--> 0x18 0x0F endtime (KerberosTime) 158 * | 159 * +--> [0xA8 0x11 renewtill tag 160 * | | 161 * | +--> 0x18 0x0F renewtill (KerberosTime)] 162 * | 163 * +--> [0xA9 L7 caddr tag 164 * | | 165 * | +--> 0x30 L7-2 caddre (HostAddresses)] 166 * | 167 * +--> [0xAA L8 authorization-data tag 168 * | 169 * +--> 0x30 L8-2 authorization-data (AuthorizationData)] 170 * </pre> 171 * 172 */ 173 @Override 174 public int computeLength() 175 { 176 flagsLen = flags.getData().length; 177 flagsLen = 1 + TLV.getNbBytes( flagsLen ) + flagsLen; 178 encTikcetPartSeqLen = 1 + TLV.getNbBytes( flagsLen ) + flagsLen; 179 180 keyLen = key.computeLength(); 181 encTikcetPartSeqLen += 1 + TLV.getNbBytes( keyLen ) + keyLen; 182 183 cRealmBytes = Strings.getBytesUtf8( cRealm ); 184 cRealmLen = 1 + TLV.getNbBytes( cRealmBytes.length ) + cRealmBytes.length; 185 encTikcetPartSeqLen += 1 + TLV.getNbBytes( cRealmLen ) + cRealmLen; 186 187 cNameLen = cName.computeLength(); 188 encTikcetPartSeqLen += 1 + TLV.getNbBytes( cNameLen ) + cNameLen; 189 190 transitedLen = transited.computeLength(); 191 encTikcetPartSeqLen += 1 + TLV.getNbBytes( transitedLen ) + transitedLen; 192 193 authTimeBytes = authTime.getBytes(); 194 authTimeLen = 1 + TLV.getNbBytes( authTimeBytes.length ) + authTimeBytes.length; 195 encTikcetPartSeqLen += 1 + TLV.getNbBytes( authTimeLen ) + authTimeLen; 196 197 if ( startTime != null ) 198 { 199 startTimeBytes = startTime.getBytes(); 200 startTimeLen = 1 + TLV.getNbBytes( startTimeBytes.length ) + startTimeBytes.length; 201 encTikcetPartSeqLen += 1 + TLV.getNbBytes( startTimeLen ) + startTimeLen; 202 } 203 204 endTimeBytes = endTime.getBytes(); 205 endTimeLen = 1 + TLV.getNbBytes( endTimeBytes.length ) + endTimeBytes.length; 206 encTikcetPartSeqLen += 1 + TLV.getNbBytes( endTimeLen ) + endTimeLen; 207 208 if ( renewtill != null ) 209 { 210 renewtillBytes = renewtill.getBytes(); 211 renewtillLen = 1 + TLV.getNbBytes( renewtillBytes.length ) + renewtillBytes.length; 212 encTikcetPartSeqLen += 1 + TLV.getNbBytes( renewtillLen ) + renewtillLen; 213 } 214 215 if ( clientAddresses != null ) 216 { 217 clientAddressesLen = clientAddresses.computeLength(); 218 encTikcetPartSeqLen += 1 + TLV.getNbBytes( clientAddressesLen ) + clientAddressesLen; 219 } 220 221 if ( authorizationData != null ) 222 { 223 authzDataLen = authorizationData.computeLength(); 224 encTikcetPartSeqLen += 1 + TLV.getNbBytes( authzDataLen ) + authzDataLen; 225 } 226 227 encTikcetPartLen = 1 + TLV.getNbBytes( encTikcetPartSeqLen ) + encTikcetPartSeqLen; 228 229 return 1 + TLV.getNbBytes( encTikcetPartLen ) + encTikcetPartLen; 230 } 231 232 233 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 234 { 235 if ( buffer == null ) 236 { 237 throw new EncoderException( I18n.err( I18n.ERR_148 ) ); 238 } 239 240 try 241 { 242 // EncTicketPart application tag and length 243 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_TAG ); 244 buffer.put( TLV.getBytes( encTikcetPartLen ) ); 245 246 // EncTicketPart sequence tag and length 247 buffer.put( UniversalTag.SEQUENCE.getValue() ); 248 buffer.put( TLV.getBytes( encTikcetPartSeqLen ) ); 249 250 // flags tag and int value 251 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_FLAGS_TAG ); 252 buffer.put( TLV.getBytes( flagsLen ) ); 253 BerValue.encode( buffer, flags ); 254 255 // key tag and value 256 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_KEY_TAG ); 257 buffer.put( TLV.getBytes( keyLen ) ); 258 key.encode( buffer ); 259 260 // crealm tag and value 261 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_CREALM_TAG ); 262 buffer.put( TLV.getBytes( cRealmLen ) ); 263 buffer.put( UniversalTag.GENERAL_STRING.getValue() ); 264 buffer.put( TLV.getBytes( cRealmBytes.length ) ); 265 buffer.put( cRealmBytes ); 266 267 // cname tag and value 268 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_CNAME_TAG ); 269 buffer.put( TLV.getBytes( cNameLen ) ); 270 cName.encode( buffer ); 271 272 // transited tag and value 273 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_TRANSITED_TAG ); 274 buffer.put( TLV.getBytes( transitedLen ) ); 275 transited.encode( buffer ); 276 277 // authtime tag and value 278 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_AUTHTIME_TAG ); 279 buffer.put( TLV.getBytes( authTimeLen ) ); 280 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() ); 281 buffer.put( ( byte ) 0x0F ); 282 buffer.put( authTimeBytes ); 283 284 if ( startTime != null ) 285 { 286 // strattime tag and value 287 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_STARTTIME_TAG ); 288 buffer.put( TLV.getBytes( startTimeLen ) ); 289 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() ); 290 buffer.put( ( byte ) 0x0F ); 291 buffer.put( startTimeBytes ); 292 } 293 294 // endtime tag and value 295 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_ENDTIME_TAG ); 296 buffer.put( TLV.getBytes( endTimeLen ) ); 297 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() ); 298 buffer.put( ( byte ) 0x0F ); 299 buffer.put( endTimeBytes ); 300 301 if ( renewtill != null ) 302 { 303 // renewtill tag and value 304 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_RENEWTILL_TAG ); 305 buffer.put( TLV.getBytes( renewtillLen ) ); 306 buffer.put( UniversalTag.GENERALIZED_TIME.getValue() ); 307 buffer.put( ( byte ) 0x0F ); 308 buffer.put( renewtillBytes ); 309 } 310 311 if ( clientAddresses != null ) 312 { 313 // caddr tag and value 314 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_CADDR_TAG ); 315 buffer.put( TLV.getBytes( clientAddressesLen ) ); 316 clientAddresses.encode( buffer ); 317 } 318 319 if ( authorizationData != null ) 320 { 321 // authorization-data tag and value 322 buffer.put( ( byte ) KerberosConstants.ENC_TICKET_PART_AUTHORIZATION_DATA_TAG ); 323 buffer.put( TLV.getBytes( authzDataLen ) ); 324 authorizationData.encode( buffer ); 325 } 326 } 327 catch ( BufferOverflowException boe ) 328 { 329 log.error( I18n.err( I18n.ERR_742_CANNOT_ENCODE_ENC_TICKET_PART, 1 + TLV.getNbBytes( encTikcetPartLen ) 330 + encTikcetPartLen, buffer.capacity() ) ); 331 throw new EncoderException( I18n.err( I18n.ERR_138 ), boe ); 332 } 333 334 if ( IS_DEBUG ) 335 { 336 log.debug( "EncTicketPart encoding : {}", Strings.dumpBytes( buffer.array() ) ); 337 log.debug( "EncTicketPart initial value : {}", this ); 338 } 339 340 return buffer; 341 } 342 343 344 /** 345 * @return the flags 346 */ 347 public TicketFlags getFlags() 348 { 349 return flags; 350 } 351 352 353 /** 354 * @param flags the flags to set 355 */ 356 public void setFlags( TicketFlags flags ) 357 { 358 this.flags = flags; 359 } 360 361 362 /** 363 * @return the key 364 */ 365 public EncryptionKey getKey() 366 { 367 return key; 368 } 369 370 371 /** 372 * @param key the key to set 373 */ 374 public void setKey( EncryptionKey key ) 375 { 376 this.key = key; 377 } 378 379 380 /** 381 * @return the cRealm 382 */ 383 public String getCRealm() 384 { 385 return cRealm; 386 } 387 388 389 /** 390 * @param cRealm the cRealm to set 391 */ 392 public void setCRealm( String cRealm ) 393 { 394 this.cRealm = cRealm; 395 } 396 397 398 /** 399 * @return the cName 400 */ 401 public PrincipalName getCName() 402 { 403 return cName; 404 } 405 406 407 /** 408 * @param cName the cName to set 409 */ 410 public void setCName( PrincipalName cName ) 411 { 412 this.cName = cName; 413 } 414 415 416 /** 417 * @return the transited 418 */ 419 public TransitedEncoding getTransited() 420 { 421 return transited; 422 } 423 424 425 /** 426 * @param transited the transited to set 427 */ 428 public void setTransited( TransitedEncoding transited ) 429 { 430 this.transited = transited; 431 } 432 433 434 /** 435 * @return the authTime 436 */ 437 public KerberosTime getAuthTime() 438 { 439 return authTime; 440 } 441 442 443 /** 444 * @param authTime the authTime to set 445 */ 446 public void setAuthTime( KerberosTime authTime ) 447 { 448 this.authTime = authTime; 449 } 450 451 452 /** 453 * @return the startTime 454 */ 455 public KerberosTime getStartTime() 456 { 457 return startTime; 458 } 459 460 461 /** 462 * @param startTime the startTime to set 463 */ 464 public void setStartTime( KerberosTime startTime ) 465 { 466 this.startTime = startTime; 467 } 468 469 470 /** 471 * @return the endTime 472 */ 473 public KerberosTime getEndTime() 474 { 475 return endTime; 476 } 477 478 479 /** 480 * @param endTime the endTime to set 481 */ 482 public void setEndTime( KerberosTime endTime ) 483 { 484 this.endTime = endTime; 485 } 486 487 488 /** 489 * @return the renewtill 490 */ 491 public KerberosTime getRenewTill() 492 { 493 return renewtill; 494 } 495 496 497 /** 498 * @param renewtill the renewtill to set 499 */ 500 public void setRenewTill( KerberosTime renewtill ) 501 { 502 this.renewtill = renewtill; 503 } 504 505 506 /** 507 * @return the clientAddresses 508 */ 509 public HostAddresses getClientAddresses() 510 { 511 return clientAddresses; 512 } 513 514 515 /** 516 * @param clientAddresses the clientAddresses to set 517 */ 518 public void setClientAddresses( HostAddresses clientAddresses ) 519 { 520 this.clientAddresses = clientAddresses; 521 } 522 523 524 /** 525 * @return the authzData 526 */ 527 public AuthorizationData getAuthorizationData() 528 { 529 return authorizationData; 530 } 531 532 533 /** 534 * @param authzData the authzData to set 535 */ 536 public void setAuthorizationData( AuthorizationData authzData ) 537 { 538 this.authorizationData = authzData; 539 } 540 541 542 /** 543 * adds the given flag to the already existing flags. 544 * If no flags exist then creates a new TicketFlags object then sets this flag 545 * and assigns the TicketFlags to this ticket part 546 * 547 * @param flag the flag to be set 548 */ 549 public void setFlag( TicketFlag flag ) 550 { 551 if ( flags == null ) 552 { 553 flags = new TicketFlags(); 554 } 555 556 flags.setFlag( flag.getValue() ); 557 } 558 559 560 /** 561 * @see Object#toString() 562 */ 563 public String toString() 564 { 565 StringBuilder sb = new StringBuilder(); 566 567 sb.append( "EncTicketPart : {\n" ); 568 569 sb.append( " flags: " ).append( flags ).append( '\n' ); 570 sb.append( " key: " ).append( key ).append( '\n' ); 571 sb.append( " cRealm: " ).append( cRealm ).append( '\n' ); 572 sb.append( " cName: " ).append( cName ).append( '\n' ); 573 sb.append( " transited: " ).append( transited ).append( '\n' ); 574 sb.append( " authTime: " ).append( authTime ).append( '\n' ); 575 576 if ( startTime != null ) 577 { 578 sb.append( " startTime: " ).append( startTime ).append( '\n' ); 579 } 580 581 sb.append( " endTime: " ).append( endTime ).append( '\n' ); 582 583 if ( renewtill != null ) 584 { 585 sb.append( " renewtill: " ).append( renewtill ).append( '\n' ); 586 } 587 588 if ( clientAddresses != null ) 589 { 590 sb.append( " clientAddresses: " ).append( clientAddresses ).append( '\n' ); 591 } 592 593 if ( authorizationData != null ) 594 { 595 sb.append( " authzData: " ).append( authorizationData ).append( '\n' ); 596 } 597 598 sb.append( "}\n" ); 599 600 return sb.toString(); 601 } 602 603}